chore(backend-docs): process with typedoc
							
								
								
									
										1
									
								
								docs/backend_api/.nojekyll
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. | ||||
							
								
								
									
										1
									
								
								docs/backend_api/assets/hierarchy.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| window.hierarchyData = "eJylk91uwyAMhd+Fa7cjdGl+XmWqIiCugkqgAmfSVOXd52y72GUibpA4Fuezjf0SKUbKov9QNxAJ7x4tuRhYeQm1HUHPKHox4l0vngSIhwuj6CvVgliS55D1OmfMbwat1QMGcuQwD9pkStrS8E//Ov/5nCeaPZv9vGUPyuNpMz79ChyYnB8TBs6skVB1ElTXwuXawPtVQn2R0HUKKlm3UFWqvq0gGlmUr9FE2k4zCzuzZCYnVgxNziyE+5nciDKm8dHsx3HPC3FJBzvtB/IHlwGR9NMNFB8Y9lN5pMqoIR75RJ7eMlx8bnt6YFJ5VcqICS1fhmN1bstZiv10+UCp6/oNzPWfkA==" | ||||
							
								
								
									
										50
									
								
								docs/backend_api/assets/highlight.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,50 @@ | ||||
| :root { | ||||
|     --light-hl-0: #795E26; | ||||
|     --dark-hl-0: #DCDCAA; | ||||
|     --light-hl-1: #000000; | ||||
|     --dark-hl-1: #D4D4D4; | ||||
|     --light-hl-2: #0000FF; | ||||
|     --dark-hl-2: #569CD6; | ||||
|     --light-hl-3: #A31515; | ||||
|     --dark-hl-3: #CE9178; | ||||
|     --light-code-background: #FFFFFF; | ||||
|     --dark-code-background: #1E1E1E; | ||||
| } | ||||
|  | ||||
| @media (prefers-color-scheme: light) { :root { | ||||
|     --hl-0: var(--light-hl-0); | ||||
|     --hl-1: var(--light-hl-1); | ||||
|     --hl-2: var(--light-hl-2); | ||||
|     --hl-3: var(--light-hl-3); | ||||
|     --code-background: var(--light-code-background); | ||||
| } } | ||||
|  | ||||
| @media (prefers-color-scheme: dark) { :root { | ||||
|     --hl-0: var(--dark-hl-0); | ||||
|     --hl-1: var(--dark-hl-1); | ||||
|     --hl-2: var(--dark-hl-2); | ||||
|     --hl-3: var(--dark-hl-3); | ||||
|     --code-background: var(--dark-code-background); | ||||
| } } | ||||
|  | ||||
| :root[data-theme='light'] { | ||||
|     --hl-0: var(--light-hl-0); | ||||
|     --hl-1: var(--light-hl-1); | ||||
|     --hl-2: var(--light-hl-2); | ||||
|     --hl-3: var(--light-hl-3); | ||||
|     --code-background: var(--light-code-background); | ||||
| } | ||||
|  | ||||
| :root[data-theme='dark'] { | ||||
|     --hl-0: var(--dark-hl-0); | ||||
|     --hl-1: var(--dark-hl-1); | ||||
|     --hl-2: var(--dark-hl-2); | ||||
|     --hl-3: var(--dark-hl-3); | ||||
|     --code-background: var(--dark-code-background); | ||||
| } | ||||
|  | ||||
| .hl-0 { color: var(--hl-0); } | ||||
| .hl-1 { color: var(--hl-1); } | ||||
| .hl-2 { color: var(--hl-2); } | ||||
| .hl-3 { color: var(--hl-3); } | ||||
| pre, code { background: var(--code-background); } | ||||
							
								
								
									
										18
									
								
								docs/backend_api/assets/icons.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1
									
								
								docs/backend_api/assets/icons.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 12 KiB | 
							
								
								
									
										60
									
								
								docs/backend_api/assets/main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1
									
								
								docs/backend_api/assets/navigation.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| window.navigationData = "eJytlltLwzAYhv9Lr8XDxNPuJu5OnOhARCSkaaTBrqnJt6mI/9006yHdIf0qYVej7/vkSZZ+7OUnAv4F0TiKOWP0iOcgQHAdHUQsFVmieB6NX5oQjTUoyoDYNLHpb5MtKKTm8UImy4zrI+epYZGdrcMUFpmpvos8icaj3esl/I0uM2hXYBnVGrtC1e6udDK6/H39PWj3TQEoSxem07sRJxtU3+WipZWIl8BRzutocOUKizOOMxn3y5apsJ6WiFRUNGcpQtLmAmuumThRDrQQBOS7WazX1gmHVXbBOO9cYi5smQpraok4RVmAkIhTXefCalZMnKjizDQJ7kidcFhlF4z1XgmNOuI6Gdq4oqJ0lfzUvaZlCCU5acb8g/xssSIHrt4o20PutDbWOTt3ZCf1SB5Ib0o++LWZo0O4Vd6LtDNvELRu+LDTci7Ny7E0BN1p+fB3ctgBV3kfcmZf/CHQpuHDPtiXc6hvp+XHr9+kYfCmg7rJ8+/CGW9gvvXc4rKwQT6+ujg5G238glhwne1jTm5vZ0/TG3I3m0/J/Pl++tjSV1QJGu8bHNvN7lqnIzOR3JmkuVoJtvc/ekyZucQJ0UyJAoi51dsDrEaQ7fD/pm27RR9658i1+3N295F5fM3TYIIla7+R+fwBbqmgig==" | ||||
							
								
								
									
										1
									
								
								docs/backend_api/assets/search.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1610
									
								
								docs/backend_api/assets/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -1,360 +0,0 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <title>JSDoc: Source: becca/entities/abstract_becca_entity.js</title> | ||||
|  | ||||
|     <script src="scripts/prettify/prettify.js"> </script> | ||||
|     <script src="scripts/prettify/lang-css.js"> </script> | ||||
|     <!--[if lt IE 9]> | ||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> | ||||
|     <![endif]--> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|  | ||||
| <div id="main"> | ||||
|  | ||||
|     <h1 class="page-title">Source: becca/entities/abstract_becca_entity.js</h1> | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
|      | ||||
|     <section> | ||||
|         <article> | ||||
|             <pre class="prettyprint source linenums"><code>"use strict"; | ||||
|  | ||||
| const utils = require('../../services/utils'); | ||||
| const sql = require('../../services/sql'); | ||||
| const entityChangesService = require('../../services/entity_changes'); | ||||
| const eventService = require("../../services/events"); | ||||
| const dateUtils = require("../../services/date_utils"); | ||||
| const cls = require("../../services/cls"); | ||||
| const log = require("../../services/log"); | ||||
| const protectedSessionService = require("../../services/protected_session"); | ||||
| const blobService = require("../../services/blob"); | ||||
|  | ||||
| let becca = null; | ||||
|  | ||||
| /** | ||||
|  * Base class for all backend entities. | ||||
|  */ | ||||
| class AbstractBeccaEntity { | ||||
|     /** @protected */ | ||||
|     beforeSaving() { | ||||
|         if (!this[this.constructor.primaryKeyName]) { | ||||
|             this[this.constructor.primaryKeyName] = utils.newEntityId(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** @protected */ | ||||
|     getUtcDateChanged() { | ||||
|         return this.utcDateModified || this.utcDateCreated; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @protected | ||||
|      * @returns {Becca} | ||||
|      */ | ||||
|     get becca() { | ||||
|         if (!becca) { | ||||
|             becca = require('../becca'); | ||||
|         } | ||||
|  | ||||
|         return becca; | ||||
|     } | ||||
|  | ||||
|     /** @protected */ | ||||
|     putEntityChange(isDeleted) { | ||||
|         entityChangesService.putEntityChange({ | ||||
|             entityName: this.constructor.entityName, | ||||
|             entityId: this[this.constructor.primaryKeyName], | ||||
|             hash: this.generateHash(isDeleted), | ||||
|             isErased: false, | ||||
|             utcDateChanged: this.getUtcDateChanged(), | ||||
|             isSynced: this.constructor.entityName !== 'options' || !!this.isSynced | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @protected | ||||
|      * @returns {string} | ||||
|      */ | ||||
|     generateHash(isDeleted) { | ||||
|         let contentToHash = ""; | ||||
|  | ||||
|         for (const propertyName of this.constructor.hashedProperties) { | ||||
|             contentToHash += `|${this[propertyName]}`; | ||||
|         } | ||||
|  | ||||
|         if (isDeleted) { | ||||
|             contentToHash += "|deleted"; | ||||
|         } | ||||
|  | ||||
|         return utils.hash(contentToHash).substr(0, 10); | ||||
|     } | ||||
|  | ||||
|     /** @protected */ | ||||
|     getPojoToSave() { | ||||
|         return this.getPojo(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @protected | ||||
|      * @abstract | ||||
|      */ | ||||
|     getPojo() { | ||||
|         throw new Error(`Unimplemented getPojo() for entity '${this.constructor.name}'`) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Saves entity - executes SQL, but doesn't commit the transaction on its own | ||||
|      * | ||||
|      * @returns {this} | ||||
|      */ | ||||
|     save(opts = {}) { | ||||
|         const entityName = this.constructor.entityName; | ||||
|         const primaryKeyName = this.constructor.primaryKeyName; | ||||
|  | ||||
|         const isNewEntity = !this[primaryKeyName]; | ||||
|  | ||||
|         this.beforeSaving(opts); | ||||
|  | ||||
|         const pojo = this.getPojoToSave(); | ||||
|  | ||||
|         sql.transactional(() => { | ||||
|             sql.upsert(entityName, primaryKeyName, pojo); | ||||
|  | ||||
|             if (entityName === 'recent_notes') { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             this.putEntityChange(!!this.isDeleted); | ||||
|  | ||||
|             if (!cls.isEntityEventsDisabled()) { | ||||
|                 const eventPayload = { | ||||
|                     entityName, | ||||
|                     entity: this | ||||
|                 }; | ||||
|  | ||||
|                 if (isNewEntity) { | ||||
|                     eventService.emit(eventService.ENTITY_CREATED, eventPayload); | ||||
|                 } | ||||
|  | ||||
|                 eventService.emit(eventService.ENTITY_CHANGED, eventPayload); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     /** @protected */ | ||||
|     _setContent(content, opts = {}) { | ||||
|         // client code asks to save entity even if blobId didn't change (something else was changed) | ||||
|         opts.forceSave = !!opts.forceSave; | ||||
|         opts.forceFrontendReload = !!opts.forceFrontendReload; | ||||
|  | ||||
|         if (content === null || content === undefined) { | ||||
|             throw new Error(`Cannot set null content to ${this.constructor.primaryKeyName} '${this[this.constructor.primaryKeyName]}'`); | ||||
|         } | ||||
|  | ||||
|         if (this.hasStringContent()) { | ||||
|             content = content.toString(); | ||||
|         } else { | ||||
|             content = Buffer.isBuffer(content) ? content : Buffer.from(content); | ||||
|         } | ||||
|  | ||||
|         const unencryptedContentForHashCalculation = this.#getUnencryptedContentForHashCalculation(content); | ||||
|  | ||||
|         if (this.isProtected) { | ||||
|             if (protectedSessionService.isProtectedSessionAvailable()) { | ||||
|                 content = protectedSessionService.encrypt(content); | ||||
|             } else { | ||||
|                 throw new Error(`Cannot update content of blob since protected session is not available.`); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         sql.transactional(() => { | ||||
|             const newBlobId = this.#saveBlob(content, unencryptedContentForHashCalculation, opts); | ||||
|             const oldBlobId = this.blobId; | ||||
|  | ||||
|             if (newBlobId !== oldBlobId || opts.forceSave) { | ||||
|                 this.blobId = newBlobId; | ||||
|                 this.save(); | ||||
|  | ||||
|                 if (newBlobId !== oldBlobId) { | ||||
|                     this.#deleteBlobIfNotUsed(oldBlobId); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     #deleteBlobIfNotUsed(oldBlobId) { | ||||
|         if (sql.getValue("SELECT 1 FROM notes WHERE blobId = ? LIMIT 1", [oldBlobId])) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (sql.getValue("SELECT 1 FROM attachments WHERE blobId = ? LIMIT 1", [oldBlobId])) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (sql.getValue("SELECT 1 FROM revisions WHERE blobId = ? LIMIT 1", [oldBlobId])) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         sql.execute("DELETE FROM blobs WHERE blobId = ?", [oldBlobId]); | ||||
|         // blobs are not marked as erased in entity_changes, they are just purged completely | ||||
|         // this is because technically every keystroke can create a new blob, and there would be just too many | ||||
|         sql.execute("DELETE FROM entity_changes WHERE entityName = 'blobs' AND entityId = ?", [oldBlobId]); | ||||
|     } | ||||
|  | ||||
|     #getUnencryptedContentForHashCalculation(unencryptedContent) { | ||||
|         if (this.isProtected) { | ||||
|             // a "random" prefix makes sure that the calculated hash/blobId is different for a decrypted/encrypted content | ||||
|             const encryptedPrefixSuffix = "t$[nvQg7q)&_ENCRYPTED_?M:Bf&j3jr_"; | ||||
|             return Buffer.isBuffer(unencryptedContent) | ||||
|                 ? Buffer.concat([Buffer.from(encryptedPrefixSuffix), unencryptedContent]) | ||||
|                 : `${encryptedPrefixSuffix}${unencryptedContent}`; | ||||
|         } else { | ||||
|             return unencryptedContent; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     #saveBlob(content, unencryptedContentForHashCalculation, opts = {}) { | ||||
|         /* | ||||
|          * We're using the unencrypted blob for the hash calculation, because otherwise the random IV would | ||||
|          * cause every content blob to be unique which would balloon the database size (esp. with revisioning). | ||||
|          * This has minor security implications (it's easy to infer that given content is shared between different | ||||
|          * notes/attachments), but the trade-off comes out clearly positive. | ||||
|          */ | ||||
|         const newBlobId = utils.hashedBlobId(unencryptedContentForHashCalculation); | ||||
|         const blobNeedsInsert = !sql.getValue('SELECT 1 FROM blobs WHERE blobId = ?', [newBlobId]); | ||||
|  | ||||
|         if (!blobNeedsInsert) { | ||||
|             return newBlobId; | ||||
|         } | ||||
|  | ||||
|         const pojo = { | ||||
|             blobId: newBlobId, | ||||
|             content: content, | ||||
|             dateModified: dateUtils.localNowDateTime(), | ||||
|             utcDateModified: dateUtils.utcNowDateTime() | ||||
|         }; | ||||
|  | ||||
|         sql.upsert("blobs", "blobId", pojo); | ||||
|  | ||||
|         // we can't reuse blobId as an entity_changes hash, because this one has to be calculatable without having | ||||
|         // access to the decrypted content | ||||
|         const hash = blobService.calculateContentHash(pojo); | ||||
|  | ||||
|         entityChangesService.putEntityChange({ | ||||
|             entityName: 'blobs', | ||||
|             entityId: newBlobId, | ||||
|             hash: hash, | ||||
|             isErased: false, | ||||
|             utcDateChanged: pojo.utcDateModified, | ||||
|             isSynced: true, | ||||
|             // overriding componentId will cause the frontend to think the change is coming from a different component | ||||
|             // and thus reload | ||||
|             componentId: opts.forceFrontendReload ? utils.randomString(10) : null | ||||
|         }); | ||||
|  | ||||
|         eventService.emit(eventService.ENTITY_CHANGED, { | ||||
|             entityName: 'blobs', | ||||
|             entity: this | ||||
|         }); | ||||
|  | ||||
|         return newBlobId; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @protected | ||||
|      * @returns {string|Buffer} | ||||
|      */ | ||||
|     _getContent() { | ||||
|         const row = sql.getRow(`SELECT content FROM blobs WHERE blobId = ?`, [this.blobId]); | ||||
|  | ||||
|         if (!row) { | ||||
|             throw new Error(`Cannot find content for ${this.constructor.primaryKeyName} '${this[this.constructor.primaryKeyName]}', blobId '${this.blobId}'`); | ||||
|         } | ||||
|  | ||||
|         return blobService.processContent(row.content, this.isProtected, this.hasStringContent()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Mark the entity as (soft) deleted. It will be completely erased later. | ||||
|      * | ||||
|      * This is a low-level method, for notes and branches use `note.deleteNote()` and 'branch.deleteBranch()` instead. | ||||
|      * | ||||
|      * @param [deleteId=null] | ||||
|      */ | ||||
|     markAsDeleted(deleteId = null) { | ||||
|         const entityId = this[this.constructor.primaryKeyName]; | ||||
|         const entityName = this.constructor.entityName; | ||||
|  | ||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); | ||||
|  | ||||
|         sql.execute(`UPDATE ${entityName} SET isDeleted = 1, deleteId = ?, utcDateModified = ? | ||||
|                            WHERE ${this.constructor.primaryKeyName} = ?`, | ||||
|             [deleteId, this.utcDateModified, entityId]); | ||||
|  | ||||
|         if (this.dateModified) { | ||||
|             this.dateModified = dateUtils.localNowDateTime(); | ||||
|  | ||||
|             sql.execute(`UPDATE ${entityName} SET dateModified = ? WHERE ${this.constructor.primaryKeyName} = ?`, | ||||
|                 [this.dateModified, entityId]); | ||||
|         } | ||||
|  | ||||
|         log.info(`Marking ${entityName} ${entityId} as deleted`); | ||||
|  | ||||
|         this.putEntityChange(true); | ||||
|  | ||||
|         eventService.emit(eventService.ENTITY_DELETED, { entityName, entityId, entity: this }); | ||||
|     } | ||||
|  | ||||
|     markAsDeletedSimple() { | ||||
|         const entityId = this[this.constructor.primaryKeyName]; | ||||
|         const entityName = this.constructor.entityName; | ||||
|  | ||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); | ||||
|  | ||||
|         sql.execute(`UPDATE ${entityName} SET isDeleted = 1, utcDateModified = ? | ||||
|                            WHERE ${this.constructor.primaryKeyName} = ?`, | ||||
|             [this.utcDateModified, entityId]); | ||||
|  | ||||
|         log.info(`Marking ${entityName} ${entityId} as deleted`); | ||||
|  | ||||
|         this.putEntityChange(true); | ||||
|  | ||||
|         eventService.emit(eventService.ENTITY_DELETED, { entityName, entityId, entity: this }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = AbstractBeccaEntity; | ||||
| </code></pre> | ||||
|         </article> | ||||
|     </section> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| </div> | ||||
|  | ||||
| <nav> | ||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> | ||||
| </nav> | ||||
|  | ||||
| <br class="clear"> | ||||
|  | ||||
| <footer> | ||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> | ||||
| </footer> | ||||
|  | ||||
| <script> prettyPrint(); </script> | ||||
| <script src="scripts/linenumber.js"> </script> | ||||
| </body> | ||||
| </html> | ||||
| @@ -1,294 +0,0 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <title>JSDoc: Source: becca/entities/battachment.js</title> | ||||
|  | ||||
|     <script src="scripts/prettify/prettify.js"> </script> | ||||
|     <script src="scripts/prettify/lang-css.js"> </script> | ||||
|     <!--[if lt IE 9]> | ||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> | ||||
|     <![endif]--> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|  | ||||
| <div id="main"> | ||||
|  | ||||
|     <h1 class="page-title">Source: becca/entities/battachment.js</h1> | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
|      | ||||
|     <section> | ||||
|         <article> | ||||
|             <pre class="prettyprint source linenums"><code>"use strict"; | ||||
|  | ||||
| const utils = require('../../services/utils'); | ||||
| const dateUtils = require('../../services/date_utils'); | ||||
| const AbstractBeccaEntity = require("./abstract_becca_entity"); | ||||
| const sql = require("../../services/sql"); | ||||
| const protectedSessionService = require("../../services/protected_session"); | ||||
| const log = require("../../services/log"); | ||||
|  | ||||
| const attachmentRoleToNoteTypeMapping = { | ||||
|     'image': 'image' | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Attachment represent data related/attached to the note. Conceptually similar to attributes, but intended for | ||||
|  * larger amounts of data and generally not accessible to the user. | ||||
|  * | ||||
|  * @extends AbstractBeccaEntity | ||||
|  */ | ||||
| class BAttachment extends AbstractBeccaEntity { | ||||
|     static get entityName() { return "attachments"; } | ||||
|     static get primaryKeyName() { return "attachmentId"; } | ||||
|     static get hashedProperties() { return ["attachmentId", "ownerId", "role", "mime", "title", "blobId", "utcDateScheduledForErasureSince"]; } | ||||
|  | ||||
|     constructor(row) { | ||||
|         super(); | ||||
|  | ||||
|         if (!row.ownerId?.trim()) { | ||||
|             throw new Error("'ownerId' must be given to initialize a Attachment entity"); | ||||
|         } else if (!row.role?.trim()) { | ||||
|             throw new Error("'role' must be given to initialize a Attachment entity"); | ||||
|         } else if (!row.mime?.trim()) { | ||||
|             throw new Error("'mime' must be given to initialize a Attachment entity"); | ||||
|         } else if (!row.title?.trim()) { | ||||
|             throw new Error("'title' must be given to initialize a Attachment entity"); | ||||
|         } | ||||
|  | ||||
|         /** @type {string} */ | ||||
|         this.attachmentId = row.attachmentId; | ||||
|         /**  | ||||
|          * either noteId or revisionId to which this attachment belongs | ||||
|          * @type {string} | ||||
|          */ | ||||
|         this.ownerId = row.ownerId; | ||||
|         /** @type {string} */ | ||||
|         this.role = row.role; | ||||
|         /** @type {string} */ | ||||
|         this.mime = row.mime; | ||||
|         /** @type {string} */ | ||||
|         this.title = row.title; | ||||
|         /** @type {int} */ | ||||
|         this.position = row.position; | ||||
|         /** @type {string} */ | ||||
|         this.blobId = row.blobId; | ||||
|         /** @type {boolean} */ | ||||
|         this.isProtected = !!row.isProtected; | ||||
|         /** @type {string} */ | ||||
|         this.dateModified = row.dateModified; | ||||
|         /** @type {string} */ | ||||
|         this.utcDateModified = row.utcDateModified; | ||||
|         /** @type {string} */ | ||||
|         this.utcDateScheduledForErasureSince = row.utcDateScheduledForErasureSince; | ||||
|  | ||||
|         /** | ||||
|          * optionally added to the entity | ||||
|          * @type {int} | ||||
|          */ | ||||
|         this.contentLength = row.contentLength; | ||||
|  | ||||
|         this.decrypt(); | ||||
|     } | ||||
|  | ||||
|     /** @returns {BAttachment} */ | ||||
|     copy() { | ||||
|         return new BAttachment({ | ||||
|             ownerId: this.ownerId, | ||||
|             role: this.role, | ||||
|             mime: this.mime, | ||||
|             title: this.title, | ||||
|             blobId: this.blobId, | ||||
|             isProtected: this.isProtected | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     /** @returns {BNote} */ | ||||
|     getNote() { | ||||
|         return this.becca.notes[this.ownerId]; | ||||
|     } | ||||
|  | ||||
|     /** @returns {boolean} true if the note has string content (not binary) */ | ||||
|     hasStringContent() { | ||||
|         return utils.isStringNote(this.type, this.mime); | ||||
|     } | ||||
|  | ||||
|     isContentAvailable() { | ||||
|         return !this.attachmentId // new attachment which was not encrypted yet | ||||
|             || !this.isProtected | ||||
|             || protectedSessionService.isProtectedSessionAvailable() | ||||
|     } | ||||
|  | ||||
|     getTitleOrProtected() { | ||||
|         return this.isContentAvailable() ? this.title : '[protected]'; | ||||
|     } | ||||
|  | ||||
|     decrypt() { | ||||
|         if (!this.isProtected || !this.attachmentId) { | ||||
|             this.isDecrypted = true; | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) { | ||||
|             try { | ||||
|                 this.title = protectedSessionService.decryptString(this.title); | ||||
|                 this.isDecrypted = true; | ||||
|             } | ||||
|             catch (e) { | ||||
|                 log.error(`Could not decrypt attachment ${this.attachmentId}: ${e.message} ${e.stack}`); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** @returns {string|Buffer}  */ | ||||
|     getContent() { | ||||
|         return this._getContent(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param content | ||||
|      * @param {object} [opts] | ||||
|      * @param {object} [opts.forceSave=false] - will also save this BAttachment entity | ||||
|      * @param {object} [opts.forceFrontendReload=false] - override frontend heuristics on when to reload, instruct to reload | ||||
|      */ | ||||
|     setContent(content, opts) { | ||||
|         this._setContent(content, opts); | ||||
|     } | ||||
|  | ||||
|     /** @returns {{note: BNote, branch: BBranch}} */ | ||||
|     convertToNote() { | ||||
|         if (this.type === 'search') { | ||||
|             throw new Error(`Note of type search cannot have child notes`); | ||||
|         } | ||||
|  | ||||
|         if (!this.getNote()) { | ||||
|             throw new Error("Cannot find note of this attachment. It is possible that this is note revision's attachment. " + | ||||
|                 "Converting note revision's attachments to note is not (yet) supported."); | ||||
|         } | ||||
|  | ||||
|         if (!(this.role in attachmentRoleToNoteTypeMapping)) { | ||||
|             throw new Error(`Mapping from attachment role '${this.role}' to note's type is not defined`); | ||||
|         } | ||||
|  | ||||
|         if (!this.isContentAvailable()) { // isProtected is the same for attachment | ||||
|             throw new Error(`Cannot convert protected attachment outside of protected session`); | ||||
|         } | ||||
|  | ||||
|         const noteService = require('../../services/notes'); | ||||
|  | ||||
|         const { note, branch } = noteService.createNewNote({ | ||||
|             parentNoteId: this.ownerId, | ||||
|             title: this.title, | ||||
|             type: attachmentRoleToNoteTypeMapping[this.role], | ||||
|             mime: this.mime, | ||||
|             content: this.getContent(), | ||||
|             isProtected: this.isProtected | ||||
|         }); | ||||
|  | ||||
|         this.markAsDeleted(); | ||||
|  | ||||
|         const parentNote = this.getNote(); | ||||
|  | ||||
|         if (this.role === 'image' && parentNote.type === 'text') { | ||||
|             const origContent = parentNote.getContent(); | ||||
|             const oldAttachmentUrl = `api/attachments/${this.attachmentId}/image/`; | ||||
|             const newNoteUrl = `api/images/${note.noteId}/`; | ||||
|  | ||||
|             const fixedContent = utils.replaceAll(origContent, oldAttachmentUrl, newNoteUrl); | ||||
|  | ||||
|             if (fixedContent !== origContent) { | ||||
|                 parentNote.setContent(fixedContent); | ||||
|             } | ||||
|  | ||||
|             noteService.asyncPostProcessContent(note, fixedContent); | ||||
|         } | ||||
|  | ||||
|         return { note, branch }; | ||||
|     } | ||||
|  | ||||
|     getFileName() { | ||||
|         const type = this.role === 'image' ? 'image' : 'file'; | ||||
|  | ||||
|         return utils.formatDownloadTitle(this.title, type, this.mime); | ||||
|     } | ||||
|  | ||||
|     beforeSaving() { | ||||
|         super.beforeSaving(); | ||||
|  | ||||
|         if (this.position === undefined || this.position === null) { | ||||
|             this.position = 10 + sql.getValue(`SELECT COALESCE(MAX(position), 0) | ||||
|                                               FROM attachments | ||||
|                                               WHERE ownerId = ?`, [this.noteId]); | ||||
|         } | ||||
|  | ||||
|         this.dateModified = dateUtils.localNowDateTime(); | ||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); | ||||
|     } | ||||
|  | ||||
|     getPojo() { | ||||
|         return { | ||||
|             attachmentId: this.attachmentId, | ||||
|             ownerId: this.ownerId, | ||||
|             role: this.role, | ||||
|             mime: this.mime, | ||||
|             title: this.title, | ||||
|             position: this.position, | ||||
|             blobId: this.blobId, | ||||
|             isProtected: !!this.isProtected, | ||||
|             isDeleted: false, | ||||
|             dateModified: this.dateModified, | ||||
|             utcDateModified: this.utcDateModified, | ||||
|             utcDateScheduledForErasureSince: this.utcDateScheduledForErasureSince, | ||||
|             contentLength: this.contentLength | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     getPojoToSave() { | ||||
|         const pojo = this.getPojo(); | ||||
|         delete pojo.contentLength; | ||||
|  | ||||
|         if (pojo.isProtected) { | ||||
|             if (this.isDecrypted) { | ||||
|                 pojo.title = protectedSessionService.encrypt(pojo.title); | ||||
|             } | ||||
|             else { | ||||
|                 // updating protected note outside of protected session means we will keep original ciphertexts | ||||
|                 delete pojo.title; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return pojo; | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = BAttachment; | ||||
| </code></pre> | ||||
|         </article> | ||||
|     </section> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| </div> | ||||
|  | ||||
| <nav> | ||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> | ||||
| </nav> | ||||
|  | ||||
| <br class="clear"> | ||||
|  | ||||
| <footer> | ||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> | ||||
| </footer> | ||||
|  | ||||
| <script> prettyPrint(); </script> | ||||
| <script src="scripts/linenumber.js"> </script> | ||||
| </body> | ||||
| </html> | ||||
| @@ -1,293 +0,0 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <title>JSDoc: Source: becca/entities/battribute.js</title> | ||||
|  | ||||
|     <script src="scripts/prettify/prettify.js"> </script> | ||||
|     <script src="scripts/prettify/lang-css.js"> </script> | ||||
|     <!--[if lt IE 9]> | ||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> | ||||
|     <![endif]--> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|  | ||||
| <div id="main"> | ||||
|  | ||||
|     <h1 class="page-title">Source: becca/entities/battribute.js</h1> | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
|      | ||||
|     <section> | ||||
|         <article> | ||||
|             <pre class="prettyprint source linenums"><code>"use strict"; | ||||
|  | ||||
| const BNote = require('./bnote'); | ||||
| const AbstractBeccaEntity = require("./abstract_becca_entity"); | ||||
| const sql = require("../../services/sql"); | ||||
| const dateUtils = require("../../services/date_utils"); | ||||
| const promotedAttributeDefinitionParser = require("../../services/promoted_attribute_definition_parser"); | ||||
| const {sanitizeAttributeName} = require("../../services/sanitize_attribute_name"); | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * There are currently only two types of attributes, labels or relations. | ||||
|  * @typedef {"label" | "relation"} AttributeType | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * Attribute is an abstract concept which has two real uses - label (key - value pair) | ||||
|  * and relation (representing named relationship between source and target note) | ||||
|  * | ||||
|  * @extends AbstractBeccaEntity | ||||
|  */ | ||||
| class BAttribute extends AbstractBeccaEntity { | ||||
|     static get entityName() { return "attributes"; } | ||||
|     static get primaryKeyName() { return "attributeId"; } | ||||
|     static get hashedProperties() { return ["attributeId", "noteId", "type", "name", "value", "isInheritable"]; } | ||||
|  | ||||
|     constructor(row) { | ||||
|         super(); | ||||
|  | ||||
|         if (!row) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this.updateFromRow(row); | ||||
|         this.init(); | ||||
|     } | ||||
|  | ||||
|     updateFromRow(row) { | ||||
|         this.update([ | ||||
|             row.attributeId, | ||||
|             row.noteId, | ||||
|             row.type, | ||||
|             row.name, | ||||
|             row.value, | ||||
|             row.isInheritable, | ||||
|             row.position, | ||||
|             row.utcDateModified | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     update([attributeId, noteId, type, name, value, isInheritable, position, utcDateModified]) { | ||||
|         /** @type {string} */ | ||||
|         this.attributeId = attributeId; | ||||
|         /** @type {string} */ | ||||
|         this.noteId = noteId; | ||||
|         /** @type {AttributeType} */ | ||||
|         this.type = type; | ||||
|         /** @type {string} */ | ||||
|         this.name = name; | ||||
|         /** @type {int} */ | ||||
|         this.position = position; | ||||
|         /** @type {string} */ | ||||
|         this.value = value || ""; | ||||
|         /** @type {boolean} */ | ||||
|         this.isInheritable = !!isInheritable; | ||||
|         /** @type {string} */ | ||||
|         this.utcDateModified = utcDateModified; | ||||
|  | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     init() { | ||||
|         if (this.attributeId) { | ||||
|             this.becca.attributes[this.attributeId] = this; | ||||
|         } | ||||
|  | ||||
|         if (!(this.noteId in this.becca.notes)) { | ||||
|             // entities can come out of order in sync, create skeleton which will be filled later | ||||
|             this.becca.addNote(this.noteId, new BNote({noteId: this.noteId})); | ||||
|         } | ||||
|  | ||||
|         this.becca.notes[this.noteId].ownedAttributes.push(this); | ||||
|  | ||||
|         const key = `${this.type}-${this.name.toLowerCase()}`; | ||||
|         this.becca.attributeIndex[key] = this.becca.attributeIndex[key] || []; | ||||
|         this.becca.attributeIndex[key].push(this); | ||||
|  | ||||
|         const targetNote = this.targetNote; | ||||
|  | ||||
|         if (targetNote) { | ||||
|             targetNote.targetRelations.push(this); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     validate() { | ||||
|         if (!["label", "relation"].includes(this.type)) { | ||||
|             throw new Error(`Invalid attribute type '${this.type}' in attribute '${this.attributeId}' of note '${this.noteId}'`); | ||||
|         } | ||||
|  | ||||
|         if (!this.name?.trim()) { | ||||
|             throw new Error(`Invalid empty name in attribute '${this.attributeId}' of note '${this.noteId}'`); | ||||
|         } | ||||
|  | ||||
|         if (this.type === 'relation' && !(this.value in this.becca.notes)) { | ||||
|             throw new Error(`Cannot save relation '${this.name}' of note '${this.noteId}' since it targets not existing note '${this.value}'.`); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     get isAffectingSubtree() { | ||||
|         return this.isInheritable | ||||
|             || (this.type === 'relation' && ['template', 'inherit'].includes(this.name)); | ||||
|     } | ||||
|  | ||||
|     get targetNoteId() { // alias | ||||
|         return this.type === 'relation' ? this.value : undefined; | ||||
|     } | ||||
|  | ||||
|     isAutoLink() { | ||||
|         return this.type === 'relation' && ['internalLink', 'imageLink', 'relationMapLink', 'includeNoteLink'].includes(this.name); | ||||
|     } | ||||
|  | ||||
|     get note() { | ||||
|         return this.becca.notes[this.noteId]; | ||||
|     } | ||||
|  | ||||
|     get targetNote() { | ||||
|         if (this.type === 'relation') { | ||||
|             return this.becca.notes[this.value]; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @returns {BNote|null} | ||||
|      */ | ||||
|     getNote() { | ||||
|         const note = this.becca.getNote(this.noteId); | ||||
|  | ||||
|         if (!note) { | ||||
|             throw new Error(`Note '${this.noteId}' of attribute '${this.attributeId}', type '${this.type}', name '${this.name}' does not exist.`); | ||||
|         } | ||||
|  | ||||
|         return note; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @returns {BNote|null} | ||||
|      */ | ||||
|     getTargetNote() { | ||||
|         if (this.type !== 'relation') { | ||||
|             throw new Error(`Attribute '${this.attributeId}' is not a relation.`); | ||||
|         } | ||||
|  | ||||
|         if (!this.value) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         return this.becca.getNote(this.value); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @returns {boolean} | ||||
|      */ | ||||
|     isDefinition() { | ||||
|         return this.type === 'label' && (this.name.startsWith('label:') || this.name.startsWith('relation:')); | ||||
|     } | ||||
|  | ||||
|     getDefinition() { | ||||
|         return promotedAttributeDefinitionParser.parse(this.value); | ||||
|     } | ||||
|  | ||||
|     getDefinedName() { | ||||
|         if (this.type === 'label' && this.name.startsWith('label:')) { | ||||
|             return this.name.substr(6); | ||||
|         } else if (this.type === 'label' && this.name.startsWith('relation:')) { | ||||
|             return this.name.substr(9); | ||||
|         } else { | ||||
|             return this.name; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     get isDeleted() { | ||||
|         return !(this.attributeId in this.becca.attributes); | ||||
|     } | ||||
|  | ||||
|     beforeSaving(opts = {}) { | ||||
|         if (!opts.skipValidation) { | ||||
|             this.validate(); | ||||
|         } | ||||
|  | ||||
|         this.name = sanitizeAttributeName(this.name); | ||||
|  | ||||
|         if (!this.value) { | ||||
|             // null value isn't allowed | ||||
|             this.value = ""; | ||||
|         } | ||||
|  | ||||
|         if (this.position === undefined || this.position === null) { | ||||
|             const maxExistingPosition = this.getNote().getAttributes() | ||||
|                 .reduce((maxPosition, attr) => Math.max(maxPosition, attr.position || 0), 0); | ||||
|  | ||||
|             this.position = maxExistingPosition + 10; | ||||
|         } | ||||
|  | ||||
|         if (!this.isInheritable) { | ||||
|             this.isInheritable = false; | ||||
|         } | ||||
|  | ||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); | ||||
|  | ||||
|         super.beforeSaving(); | ||||
|  | ||||
|         this.becca.attributes[this.attributeId] = this; | ||||
|     } | ||||
|  | ||||
|     getPojo() { | ||||
|         return { | ||||
|             attributeId: this.attributeId, | ||||
|             noteId: this.noteId, | ||||
|             type: this.type, | ||||
|             name: this.name, | ||||
|             position: this.position, | ||||
|             value: this.value, | ||||
|             isInheritable: this.isInheritable, | ||||
|             utcDateModified: this.utcDateModified, | ||||
|             isDeleted: false | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     createClone(type, name, value, isInheritable) { | ||||
|         return new BAttribute({ | ||||
|             noteId: this.noteId, | ||||
|             type: type, | ||||
|             name: name, | ||||
|             value: value, | ||||
|             position: this.position, | ||||
|             isInheritable: isInheritable, | ||||
|             utcDateModified: this.utcDateModified | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = BAttribute; | ||||
| </code></pre> | ||||
|         </article> | ||||
|     </section> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| </div> | ||||
|  | ||||
| <nav> | ||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> | ||||
| </nav> | ||||
|  | ||||
| <br class="clear"> | ||||
|  | ||||
| <footer> | ||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> | ||||
| </footer> | ||||
|  | ||||
| <script> prettyPrint(); </script> | ||||
| <script src="scripts/linenumber.js"> </script> | ||||
| </body> | ||||
| </html> | ||||
| @@ -1,81 +0,0 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <title>JSDoc: Source: becca/entities/bblob.js</title> | ||||
|  | ||||
|     <script src="scripts/prettify/prettify.js"> </script> | ||||
|     <script src="scripts/prettify/lang-css.js"> </script> | ||||
|     <!--[if lt IE 9]> | ||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> | ||||
|     <![endif]--> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|  | ||||
| <div id="main"> | ||||
|  | ||||
|     <h1 class="page-title">Source: becca/entities/bblob.js</h1> | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
|      | ||||
|     <section> | ||||
|         <article> | ||||
|             <pre class="prettyprint source linenums"><code>class BBlob { | ||||
|     static get entityName() { return "blobs"; } | ||||
|     static get primaryKeyName() { return "blobId"; } | ||||
|     static get hashedProperties() { return ["blobId", "content"]; } | ||||
|  | ||||
|     constructor(row) { | ||||
|         /** @type {string} */ | ||||
|         this.blobId = row.blobId; | ||||
|         /** @type {string|Buffer} */ | ||||
|         this.content = row.content; | ||||
|         /** @type {int} */ | ||||
|         this.contentLength = row.contentLength; | ||||
|         /** @type {string} */ | ||||
|         this.dateModified = row.dateModified; | ||||
|         /** @type {string} */ | ||||
|         this.utcDateModified = row.utcDateModified; | ||||
|     } | ||||
|  | ||||
|     getPojo() { | ||||
|         return { | ||||
|             blobId: this.blobId, | ||||
|             content: this.content, | ||||
|             contentLength: this.contentLength, | ||||
|             dateModified: this.dateModified, | ||||
|             utcDateModified: this.utcDateModified | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = BBlob; | ||||
| </code></pre> | ||||
|         </article> | ||||
|     </section> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| </div> | ||||
|  | ||||
| <nav> | ||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> | ||||
| </nav> | ||||
|  | ||||
| <br class="clear"> | ||||
|  | ||||
| <footer> | ||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> | ||||
| </footer> | ||||
|  | ||||
| <script> prettyPrint(); </script> | ||||
| <script src="scripts/linenumber.js"> </script> | ||||
| </body> | ||||
| </html> | ||||
| @@ -1,333 +0,0 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <title>JSDoc: Source: becca/entities/bbranch.js</title> | ||||
|  | ||||
|     <script src="scripts/prettify/prettify.js"> </script> | ||||
|     <script src="scripts/prettify/lang-css.js"> </script> | ||||
|     <!--[if lt IE 9]> | ||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> | ||||
|     <![endif]--> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|  | ||||
| <div id="main"> | ||||
|  | ||||
|     <h1 class="page-title">Source: becca/entities/bbranch.js</h1> | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
|      | ||||
|     <section> | ||||
|         <article> | ||||
|             <pre class="prettyprint source linenums"><code>"use strict"; | ||||
|  | ||||
| const BNote = require('./bnote'); | ||||
| const AbstractBeccaEntity = require("./abstract_becca_entity"); | ||||
| const dateUtils = require("../../services/date_utils"); | ||||
| const utils = require("../../services/utils"); | ||||
| const TaskContext = require("../../services/task_context"); | ||||
| const cls = require("../../services/cls"); | ||||
| const log = require("../../services/log"); | ||||
|  | ||||
| /** | ||||
|  * Branch represents a relationship between a child note and its parent note. Trilium allows a note to have multiple | ||||
|  * parents. | ||||
|  * | ||||
|  * Note that you should not rely on the branch's identity, since it can change easily with a note's move. | ||||
|  * Always check noteId instead. | ||||
|  * | ||||
|  * @extends AbstractBeccaEntity | ||||
|  */ | ||||
| class BBranch extends AbstractBeccaEntity { | ||||
|     static get entityName() { return "branches"; } | ||||
|     static get primaryKeyName() { return "branchId"; } | ||||
|     // notePosition is not part of hash because it would produce a lot of updates in case of reordering | ||||
|     static get hashedProperties() { return ["branchId", "noteId", "parentNoteId", "prefix"]; } | ||||
|  | ||||
|     constructor(row) { | ||||
|         super(); | ||||
|  | ||||
|         if (!row) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this.updateFromRow(row); | ||||
|         this.init(); | ||||
|     } | ||||
|  | ||||
|     updateFromRow(row) { | ||||
|         this.update([ | ||||
|             row.branchId, | ||||
|             row.noteId, | ||||
|             row.parentNoteId, | ||||
|             row.prefix, | ||||
|             row.notePosition, | ||||
|             row.isExpanded, | ||||
|             row.utcDateModified | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     update([branchId, noteId, parentNoteId, prefix, notePosition, isExpanded, utcDateModified]) { | ||||
|         /** @type {string} */ | ||||
|         this.branchId = branchId; | ||||
|         /** @type {string} */ | ||||
|         this.noteId = noteId; | ||||
|         /** @type {string} */ | ||||
|         this.parentNoteId = parentNoteId; | ||||
|         /** @type {string|null} */ | ||||
|         this.prefix = prefix; | ||||
|         /** @type {int} */ | ||||
|         this.notePosition = notePosition; | ||||
|         /** @type {boolean} */ | ||||
|         this.isExpanded = !!isExpanded; | ||||
|         /** @type {string} */ | ||||
|         this.utcDateModified = utcDateModified; | ||||
|  | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     init() { | ||||
|         if (this.branchId) { | ||||
|             this.becca.branches[this.branchId] = this; | ||||
|         } | ||||
|  | ||||
|         this.becca.childParentToBranch[`${this.noteId}-${this.parentNoteId}`] = this; | ||||
|  | ||||
|         const childNote = this.childNote; | ||||
|  | ||||
|         if (!childNote.parentBranches.includes(this)) { | ||||
|             childNote.parentBranches.push(this); | ||||
|         } | ||||
|  | ||||
|         if (this.noteId === 'root') { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         const parentNote = this.parentNote; | ||||
|  | ||||
|         if (!childNote.parents.includes(parentNote)) { | ||||
|             childNote.parents.push(parentNote); | ||||
|         } | ||||
|  | ||||
|         if (!parentNote.children.includes(childNote)) { | ||||
|             parentNote.children.push(childNote); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** @returns {BNote} */ | ||||
|     get childNote() { | ||||
|         if (!(this.noteId in this.becca.notes)) { | ||||
|             // entities can come out of order in sync/import, create skeleton which will be filled later | ||||
|             this.becca.addNote(this.noteId, new BNote({noteId: this.noteId})); | ||||
|         } | ||||
|  | ||||
|         return this.becca.notes[this.noteId]; | ||||
|     } | ||||
|  | ||||
|     /** @returns {BNote} */ | ||||
|     getNote() { | ||||
|         return this.childNote; | ||||
|     } | ||||
|  | ||||
|     /** @returns {BNote|undefined} - root branch will have undefined parent, all other branches have to have a parent note */ | ||||
|     get parentNote() { | ||||
|         if (!(this.parentNoteId in this.becca.notes) && this.parentNoteId !== 'none') { | ||||
|             // entities can come out of order in sync/import, create skeleton which will be filled later | ||||
|             this.becca.addNote(this.parentNoteId, new BNote({noteId: this.parentNoteId})); | ||||
|         } | ||||
|  | ||||
|         return this.becca.notes[this.parentNoteId]; | ||||
|     } | ||||
|  | ||||
|     get isDeleted() { | ||||
|         return !(this.branchId in this.becca.branches); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Branch is weak when its existence should not hinder deletion of its note. | ||||
|      * As a result, note with only weak branches should be immediately deleted. | ||||
|      * An example is shared or bookmarked clones - they are created automatically and exist for technical reasons, | ||||
|      * not as user-intended actions. From user perspective, they don't count as real clones and for the purpose | ||||
|      * of deletion should not act as a clone. | ||||
|      * | ||||
|      * @returns {boolean} | ||||
|      */ | ||||
|     get isWeak() { | ||||
|         return ['_share', '_lbBookmarks'].includes(this.parentNoteId); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Delete a branch. If this is a last note's branch, delete the note as well. | ||||
|      * | ||||
|      * @param {string} [deleteId] - optional delete identified | ||||
|      * @param {TaskContext} [taskContext] | ||||
|      * | ||||
|      * @returns {boolean} - true if note has been deleted, false otherwise | ||||
|      */ | ||||
|     deleteBranch(deleteId, taskContext) { | ||||
|         if (!deleteId) { | ||||
|             deleteId = utils.randomString(10); | ||||
|         } | ||||
|  | ||||
|         if (!taskContext) { | ||||
|             taskContext = new TaskContext('no-progress-reporting'); | ||||
|         } | ||||
|  | ||||
|         taskContext.increaseProgressCount(); | ||||
|  | ||||
|         const note = this.getNote(); | ||||
|  | ||||
|         if (!taskContext.noteDeletionHandlerTriggered) { | ||||
|             const parentBranches = note.getParentBranches(); | ||||
|  | ||||
|             if (parentBranches.length === 1 && parentBranches[0] === this) { | ||||
|                 // needs to be run before branches and attributes are deleted and thus attached relations disappear | ||||
|                 const handlers = require("../../services/handlers"); | ||||
|                 handlers.runAttachedRelations(note, 'runOnNoteDeletion', note); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (this.noteId === 'root' | ||||
|             || this.noteId === cls.getHoistedNoteId()) { | ||||
|  | ||||
|             throw new Error("Can't delete root or hoisted branch/note"); | ||||
|         } | ||||
|  | ||||
|         this.markAsDeleted(deleteId); | ||||
|  | ||||
|         const notDeletedBranches = note.getStrongParentBranches(); | ||||
|  | ||||
|         if (notDeletedBranches.length === 0) { | ||||
|             for (const weakBranch of note.getParentBranches()) { | ||||
|                 weakBranch.markAsDeleted(deleteId); | ||||
|             } | ||||
|  | ||||
|             for (const childBranch of note.getChildBranches()) { | ||||
|                 childBranch.deleteBranch(deleteId, taskContext); | ||||
|             } | ||||
|  | ||||
|             // first delete children and then parent - this will show up better in recent changes | ||||
|  | ||||
|             log.info(`Deleting note '${note.noteId}'`); | ||||
|  | ||||
|             this.becca.notes[note.noteId].isBeingDeleted = true; | ||||
|  | ||||
|             for (const attribute of note.getOwnedAttributes().slice()) { | ||||
|                 attribute.markAsDeleted(deleteId); | ||||
|             } | ||||
|  | ||||
|             for (const relation of note.getTargetRelations()) { | ||||
|                 relation.markAsDeleted(deleteId); | ||||
|             } | ||||
|  | ||||
|             for (const attachment of note.getAttachments()) { | ||||
|                 attachment.markAsDeleted(deleteId); | ||||
|             } | ||||
|  | ||||
|             note.markAsDeleted(deleteId); | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|         else { | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     beforeSaving() { | ||||
|         if (!this.noteId || !this.parentNoteId) { | ||||
|             throw new Error(`noteId and parentNoteId are mandatory properties for Branch`); | ||||
|         } | ||||
|  | ||||
|         this.branchId = `${this.parentNoteId}_${this.noteId}`; | ||||
|  | ||||
|         if (this.notePosition === undefined || this.notePosition === null) { | ||||
|             let maxNotePos = 0; | ||||
|  | ||||
|             for (const childBranch of this.parentNote.getChildBranches()) { | ||||
|                 if (maxNotePos < childBranch.notePosition | ||||
|                     && childBranch.noteId !== '_hidden' // hidden has a very large notePosition to always stay last | ||||
|                 ) { | ||||
|                     maxNotePos = childBranch.notePosition; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             this.notePosition = maxNotePos + 10; | ||||
|         } | ||||
|  | ||||
|         if (!this.isExpanded) { | ||||
|             this.isExpanded = false; | ||||
|         } | ||||
|  | ||||
|         if (!this.prefix?.trim()) { | ||||
|             this.prefix = null; | ||||
|         } | ||||
|  | ||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); | ||||
|  | ||||
|         super.beforeSaving(); | ||||
|  | ||||
|         this.becca.branches[this.branchId] = this; | ||||
|     } | ||||
|  | ||||
|     getPojo() { | ||||
|         return { | ||||
|             branchId: this.branchId, | ||||
|             noteId: this.noteId, | ||||
|             parentNoteId: this.parentNoteId, | ||||
|             prefix: this.prefix, | ||||
|             notePosition: this.notePosition, | ||||
|             isExpanded: this.isExpanded, | ||||
|             isDeleted: false, | ||||
|             utcDateModified: this.utcDateModified | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     createClone(parentNoteId, notePosition) { | ||||
|         const existingBranch = this.becca.getBranchFromChildAndParent(this.noteId, parentNoteId); | ||||
|  | ||||
|         if (existingBranch) { | ||||
|             existingBranch.notePosition = notePosition; | ||||
|             return existingBranch; | ||||
|         } else { | ||||
|             return new BBranch({ | ||||
|                 noteId: this.noteId, | ||||
|                 parentNoteId: parentNoteId, | ||||
|                 notePosition: notePosition, | ||||
|                 prefix: this.prefix, | ||||
|                 isExpanded: this.isExpanded | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = BBranch; | ||||
| </code></pre> | ||||
|         </article> | ||||
|     </section> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| </div> | ||||
|  | ||||
| <nav> | ||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> | ||||
| </nav> | ||||
|  | ||||
| <br class="clear"> | ||||
|  | ||||
| <footer> | ||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> | ||||
| </footer> | ||||
|  | ||||
| <script> prettyPrint(); </script> | ||||
| <script src="scripts/linenumber.js"> </script> | ||||
| </body> | ||||
| </html> | ||||
| @@ -1,129 +0,0 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <title>JSDoc: Source: becca/entities/betapi_token.js</title> | ||||
|  | ||||
|     <script src="scripts/prettify/prettify.js"> </script> | ||||
|     <script src="scripts/prettify/lang-css.js"> </script> | ||||
|     <!--[if lt IE 9]> | ||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> | ||||
|     <![endif]--> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|  | ||||
| <div id="main"> | ||||
|  | ||||
|     <h1 class="page-title">Source: becca/entities/betapi_token.js</h1> | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
|      | ||||
|     <section> | ||||
|         <article> | ||||
|             <pre class="prettyprint source linenums"><code>"use strict"; | ||||
|  | ||||
| const dateUtils = require('../../services/date_utils'); | ||||
| const AbstractBeccaEntity = require("./abstract_becca_entity"); | ||||
|  | ||||
| /** | ||||
|  * EtapiToken is an entity representing token used to authenticate against Trilium REST API from client applications. | ||||
|  * Used by: | ||||
|  * - Trilium Sender | ||||
|  * - ETAPI clients | ||||
|  * | ||||
|  * The format user is presented with is "<etapiTokenId>_<tokenHash>". This is also called "authToken" to distinguish it | ||||
|  * from tokenHash and token. | ||||
|  * | ||||
|  * @extends AbstractBeccaEntity | ||||
|  */ | ||||
| class BEtapiToken extends AbstractBeccaEntity { | ||||
|     static get entityName() { return "etapi_tokens"; } | ||||
|     static get primaryKeyName() { return "etapiTokenId"; } | ||||
|     static get hashedProperties() { return ["etapiTokenId", "name", "tokenHash", "utcDateCreated", "utcDateModified", "isDeleted"]; } | ||||
|  | ||||
|     constructor(row) { | ||||
|         super(); | ||||
|  | ||||
|         if (!row) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this.updateFromRow(row); | ||||
|         this.init(); | ||||
|     } | ||||
|  | ||||
|     updateFromRow(row) { | ||||
|         /** @type {string} */ | ||||
|         this.etapiTokenId = row.etapiTokenId; | ||||
|         /** @type {string} */ | ||||
|         this.name = row.name; | ||||
|         /** @type {string} */ | ||||
|         this.tokenHash = row.tokenHash; | ||||
|         /** @type {string} */ | ||||
|         this.utcDateCreated = row.utcDateCreated || dateUtils.utcNowDateTime(); | ||||
|         /** @type {string} */ | ||||
|         this.utcDateModified = row.utcDateModified || this.utcDateCreated; | ||||
|         /** @type {boolean} */ | ||||
|         this.isDeleted = !!row.isDeleted; | ||||
|  | ||||
|         if (this.etapiTokenId) { | ||||
|             this.becca.etapiTokens[this.etapiTokenId] = this; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     init() { | ||||
|         if (this.etapiTokenId) { | ||||
|             this.becca.etapiTokens[this.etapiTokenId] = this; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     getPojo() { | ||||
|         return { | ||||
|             etapiTokenId: this.etapiTokenId, | ||||
|             name: this.name, | ||||
|             tokenHash: this.tokenHash, | ||||
|             utcDateCreated: this.utcDateCreated, | ||||
|             utcDateModified: this.utcDateModified, | ||||
|             isDeleted: this.isDeleted | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     beforeSaving() { | ||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); | ||||
|  | ||||
|         super.beforeSaving(); | ||||
|  | ||||
|         this.becca.etapiTokens[this.etapiTokenId] = this; | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = BEtapiToken; | ||||
| </code></pre> | ||||
|         </article> | ||||
|     </section> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| </div> | ||||
|  | ||||
| <nav> | ||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> | ||||
| </nav> | ||||
|  | ||||
| <br class="clear"> | ||||
|  | ||||
| <footer> | ||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> | ||||
| </footer> | ||||
|  | ||||
| <script> prettyPrint(); </script> | ||||
| <script src="scripts/linenumber.js"> </script> | ||||
| </body> | ||||
| </html> | ||||
| @@ -1,101 +0,0 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <title>JSDoc: Source: becca/entities/boption.js</title> | ||||
|  | ||||
|     <script src="scripts/prettify/prettify.js"> </script> | ||||
|     <script src="scripts/prettify/lang-css.js"> </script> | ||||
|     <!--[if lt IE 9]> | ||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> | ||||
|     <![endif]--> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|  | ||||
| <div id="main"> | ||||
|  | ||||
|     <h1 class="page-title">Source: becca/entities/boption.js</h1> | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
|      | ||||
|     <section> | ||||
|         <article> | ||||
|             <pre class="prettyprint source linenums"><code>"use strict"; | ||||
|  | ||||
| const dateUtils = require('../../services/date_utils'); | ||||
| const AbstractBeccaEntity = require("./abstract_becca_entity"); | ||||
|  | ||||
| /** | ||||
|  * Option represents a name-value pair, either directly configurable by the user or some system property. | ||||
|  * | ||||
|  * @extends AbstractBeccaEntity | ||||
|  */ | ||||
| class BOption extends AbstractBeccaEntity { | ||||
|     static get entityName() { return "options"; } | ||||
|     static get primaryKeyName() { return "name"; } | ||||
|     static get hashedProperties() { return ["name", "value"]; } | ||||
|  | ||||
|     constructor(row) { | ||||
|         super(); | ||||
|  | ||||
|         this.updateFromRow(row); | ||||
|         this.becca.options[this.name] = this; | ||||
|     } | ||||
|  | ||||
|     updateFromRow(row) { | ||||
|         /** @type {string} */ | ||||
|         this.name = row.name; | ||||
|         /** @type {string} */ | ||||
|         this.value = row.value; | ||||
|         /** @type {boolean} */ | ||||
|         this.isSynced = !!row.isSynced; | ||||
|         /** @type {string} */ | ||||
|         this.utcDateModified = row.utcDateModified; | ||||
|     } | ||||
|  | ||||
|     beforeSaving() { | ||||
|         super.beforeSaving(); | ||||
|  | ||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); | ||||
|     } | ||||
|  | ||||
|     getPojo() { | ||||
|         return { | ||||
|             name: this.name, | ||||
|             value: this.value, | ||||
|             isSynced: this.isSynced, | ||||
|             utcDateModified: this.utcDateModified | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = BOption; | ||||
| </code></pre> | ||||
|         </article> | ||||
|     </section> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| </div> | ||||
|  | ||||
| <nav> | ||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> | ||||
| </nav> | ||||
|  | ||||
| <br class="clear"> | ||||
|  | ||||
| <footer> | ||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> | ||||
| </footer> | ||||
|  | ||||
| <script> prettyPrint(); </script> | ||||
| <script src="scripts/linenumber.js"> </script> | ||||
| </body> | ||||
| </html> | ||||
| @@ -1,86 +0,0 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <title>JSDoc: Source: becca/entities/brecent_note.js</title> | ||||
|  | ||||
|     <script src="scripts/prettify/prettify.js"> </script> | ||||
|     <script src="scripts/prettify/lang-css.js"> </script> | ||||
|     <!--[if lt IE 9]> | ||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> | ||||
|     <![endif]--> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|  | ||||
| <div id="main"> | ||||
|  | ||||
|     <h1 class="page-title">Source: becca/entities/brecent_note.js</h1> | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
|      | ||||
|     <section> | ||||
|         <article> | ||||
|             <pre class="prettyprint source linenums"><code>"use strict"; | ||||
|  | ||||
| const dateUtils = require('../../services/date_utils'); | ||||
| const AbstractBeccaEntity = require("./abstract_becca_entity"); | ||||
|  | ||||
| /** | ||||
|  * RecentNote represents recently visited note. | ||||
|  * | ||||
|  * @extends AbstractBeccaEntity | ||||
|  */ | ||||
| class BRecentNote extends AbstractBeccaEntity { | ||||
|     static get entityName() { return "recent_notes"; } | ||||
|     static get primaryKeyName() { return "noteId"; } | ||||
|  | ||||
|     constructor(row) { | ||||
|         super(); | ||||
|  | ||||
|         /** @type {string} */ | ||||
|         this.noteId = row.noteId; | ||||
|         /** @type {string} */ | ||||
|         this.notePath = row.notePath; | ||||
|         /** @type {string} */ | ||||
|         this.utcDateCreated = row.utcDateCreated || dateUtils.utcNowDateTime(); | ||||
|     } | ||||
|  | ||||
|     getPojo() { | ||||
|         return { | ||||
|             noteId: this.noteId, | ||||
|             notePath: this.notePath, | ||||
|             utcDateCreated: this.utcDateCreated | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = BRecentNote; | ||||
| </code></pre> | ||||
|         </article> | ||||
|     </section> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| </div> | ||||
|  | ||||
| <nav> | ||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> | ||||
| </nav> | ||||
|  | ||||
| <br class="clear"> | ||||
|  | ||||
| <footer> | ||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> | ||||
| </footer> | ||||
|  | ||||
| <script> prettyPrint(); </script> | ||||
| <script src="scripts/linenumber.js"> </script> | ||||
| </body> | ||||
| </html> | ||||
| @@ -1,259 +0,0 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <title>JSDoc: Source: becca/entities/brevision.js</title> | ||||
|  | ||||
|     <script src="scripts/prettify/prettify.js"> </script> | ||||
|     <script src="scripts/prettify/lang-css.js"> </script> | ||||
|     <!--[if lt IE 9]> | ||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> | ||||
|     <![endif]--> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|  | ||||
| <div id="main"> | ||||
|  | ||||
|     <h1 class="page-title">Source: becca/entities/brevision.js</h1> | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
|      | ||||
|     <section> | ||||
|         <article> | ||||
|             <pre class="prettyprint source linenums"><code>"use strict"; | ||||
|  | ||||
| const protectedSessionService = require('../../services/protected_session'); | ||||
| const utils = require('../../services/utils'); | ||||
| const dateUtils = require('../../services/date_utils'); | ||||
| const becca = require('../becca'); | ||||
| const AbstractBeccaEntity = require("./abstract_becca_entity"); | ||||
| const sql = require("../../services/sql"); | ||||
| const BAttachment = require("./battachment"); | ||||
|  | ||||
| /** | ||||
|  * Revision represents a snapshot of note's title and content at some point in the past. | ||||
|  * It's used for seamless note versioning. | ||||
|  * | ||||
|  * @extends AbstractBeccaEntity | ||||
|  */ | ||||
| class BRevision extends AbstractBeccaEntity { | ||||
|     static get entityName() { return "revisions"; } | ||||
|     static get primaryKeyName() { return "revisionId"; } | ||||
|     static get hashedProperties() { return ["revisionId", "noteId", "title", "isProtected", "dateLastEdited", "dateCreated", | ||||
|                                             "utcDateLastEdited", "utcDateCreated", "utcDateModified", "blobId"]; } | ||||
|  | ||||
|     constructor(row, titleDecrypted = false) { | ||||
|         super(); | ||||
|  | ||||
|         /** @type {string} */ | ||||
|         this.revisionId = row.revisionId; | ||||
|         /** @type {string} */ | ||||
|         this.noteId = row.noteId; | ||||
|         /** @type {string} */ | ||||
|         this.type = row.type; | ||||
|         /** @type {string} */ | ||||
|         this.mime = row.mime; | ||||
|         /** @type {boolean} */ | ||||
|         this.isProtected = !!row.isProtected; | ||||
|         /** @type {string} */ | ||||
|         this.title = row.title; | ||||
|         /** @type {string} */ | ||||
|         this.blobId = row.blobId; | ||||
|         /** @type {string} */ | ||||
|         this.dateLastEdited = row.dateLastEdited; | ||||
|         /** @type {string} */ | ||||
|         this.dateCreated = row.dateCreated; | ||||
|         /** @type {string} */ | ||||
|         this.utcDateLastEdited = row.utcDateLastEdited; | ||||
|         /** @type {string} */ | ||||
|         this.utcDateCreated = row.utcDateCreated; | ||||
|         /** @type {string} */ | ||||
|         this.utcDateModified = row.utcDateModified; | ||||
|         /** @type {int} */ | ||||
|         this.contentLength = row.contentLength; | ||||
|  | ||||
|         if (this.isProtected && !titleDecrypted) { | ||||
|             this.title = protectedSessionService.isProtectedSessionAvailable() | ||||
|                 ? protectedSessionService.decryptString(this.title) | ||||
|                 : "[protected]"; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     getNote() { | ||||
|         return becca.notes[this.noteId]; | ||||
|     } | ||||
|  | ||||
|     /** @returns {boolean} true if the note has string content (not binary) */ | ||||
|     hasStringContent() { | ||||
|         return utils.isStringNote(this.type, this.mime); | ||||
|     } | ||||
|  | ||||
|     isContentAvailable() { | ||||
|         return !this.revisionId // new note which was not encrypted yet | ||||
|             || !this.isProtected | ||||
|             || protectedSessionService.isProtectedSessionAvailable() | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|      * Note revision content has quite special handling - it's not a separate entity, but a lazily loaded | ||||
|      * part of Revision entity with its own sync. The reason behind this hybrid design is that | ||||
|      * content can be quite large, and it's not necessary to load it / fill memory for any note access even | ||||
|      * if we don't need a content, especially for bulk operations like search. | ||||
|      * | ||||
|      * This is the same approach as is used for Note's content. | ||||
|      */ | ||||
|  | ||||
|     /** @returns {string|Buffer} */ | ||||
|     getContent() { | ||||
|         return this._getContent(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @returns {*} | ||||
|      * @throws Error in case of invalid JSON */ | ||||
|     getJsonContent() { | ||||
|         const content = this.getContent(); | ||||
|  | ||||
|         if (!content || !content.trim()) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         return JSON.parse(content); | ||||
|     } | ||||
|  | ||||
|     /** @returns {*|null} valid object or null if the content cannot be parsed as JSON */ | ||||
|     getJsonContentSafely() { | ||||
|         try { | ||||
|             return this.getJsonContent(); | ||||
|         } | ||||
|         catch (e) { | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param content | ||||
|      * @param {object} [opts] | ||||
|      * @param {object} [opts.forceSave=false] - will also save this BRevision entity | ||||
|      */ | ||||
|     setContent(content, opts) { | ||||
|         this._setContent(content, opts); | ||||
|     } | ||||
|  | ||||
|     /** @returns {BAttachment[]} */ | ||||
|     getAttachments() { | ||||
|         return sql.getRows(` | ||||
|                 SELECT attachments.* | ||||
|                 FROM attachments  | ||||
|                 WHERE ownerId = ?  | ||||
|                   AND isDeleted = 0`, [this.revisionId]) | ||||
|             .map(row => new BAttachment(row)); | ||||
|     } | ||||
|  | ||||
|     /** @returns {BAttachment|null} */ | ||||
|     getAttachmentById(attachmentId, opts = {}) { | ||||
|         opts.includeContentLength = !!opts.includeContentLength; | ||||
|  | ||||
|         const query = opts.includeContentLength | ||||
|             ? `SELECT attachments.*, LENGTH(blobs.content) AS contentLength | ||||
|                FROM attachments  | ||||
|                JOIN blobs USING (blobId)  | ||||
|                WHERE ownerId = ? AND attachmentId = ? AND isDeleted = 0` | ||||
|             : `SELECT * FROM attachments WHERE ownerId = ? AND attachmentId = ? AND isDeleted = 0`; | ||||
|  | ||||
|         return sql.getRows(query, [this.revisionId, attachmentId]) | ||||
|             .map(row => new BAttachment(row))[0]; | ||||
|     } | ||||
|  | ||||
|     /** @returns {BAttachment[]} */ | ||||
|     getAttachmentsByRole(role) { | ||||
|         return sql.getRows(` | ||||
|                 SELECT attachments.* | ||||
|                 FROM attachments  | ||||
|                 WHERE ownerId = ?  | ||||
|                   AND role = ? | ||||
|                   AND isDeleted = 0 | ||||
|                 ORDER BY position`, [this.revisionId, role]) | ||||
|             .map(row => new BAttachment(row)); | ||||
|     } | ||||
|  | ||||
|     /** @returns {BAttachment} */ | ||||
|     getAttachmentByTitle(title) { | ||||
|         // cannot use SQL to filter by title since it can be encrypted | ||||
|         return this.getAttachments().filter(attachment => attachment.title === title)[0]; | ||||
|     } | ||||
|  | ||||
|     beforeSaving() { | ||||
|         super.beforeSaving(); | ||||
|  | ||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); | ||||
|     } | ||||
|  | ||||
|     getPojo() { | ||||
|         return { | ||||
|             revisionId: this.revisionId, | ||||
|             noteId: this.noteId, | ||||
|             type: this.type, | ||||
|             mime: this.mime, | ||||
|             isProtected: this.isProtected, | ||||
|             title: this.title, | ||||
|             blobId: this.blobId, | ||||
|             dateLastEdited: this.dateLastEdited, | ||||
|             dateCreated: this.dateCreated, | ||||
|             utcDateLastEdited: this.utcDateLastEdited, | ||||
|             utcDateCreated: this.utcDateCreated, | ||||
|             utcDateModified: this.utcDateModified, | ||||
|             content: this.content, // used when retrieving full note revision to frontend | ||||
|             contentLength: this.contentLength | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     getPojoToSave() { | ||||
|         const pojo = this.getPojo(); | ||||
|         delete pojo.content; // not getting persisted | ||||
|         delete pojo.contentLength; // not getting persisted | ||||
|  | ||||
|         if (pojo.isProtected) { | ||||
|             if (protectedSessionService.isProtectedSessionAvailable()) { | ||||
|                 pojo.title = protectedSessionService.encrypt(this.title); | ||||
|             } | ||||
|             else { | ||||
|                 // updating protected note outside of protected session means we will keep original ciphertexts | ||||
|                 delete pojo.title; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return pojo; | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = BRevision; | ||||
| </code></pre> | ||||
|         </article> | ||||
|     </section> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| </div> | ||||
|  | ||||
| <nav> | ||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> | ||||
| </nav> | ||||
|  | ||||
| <br class="clear"> | ||||
|  | ||||
| <footer> | ||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> | ||||
| </footer> | ||||
|  | ||||
| <script> prettyPrint(); </script> | ||||
| <script src="scripts/linenumber.js"> </script> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										34
									
								
								docs/backend_api/classes/becca_entities_bblob.default.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										57
									
								
								docs/backend_api/classes/becca_entities_bbranch.default.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										347
									
								
								docs/backend_api/classes/becca_entities_bnote.default.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										34
									
								
								docs/backend_api/classes/becca_entities_boption.default.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| Before Width: | Height: | Size: 116 KiB | 
| Before Width: | Height: | Size: 118 KiB | 
| Before Width: | Height: | Size: 120 KiB | 
| Before Width: | Height: | Size: 114 KiB | 
| Before Width: | Height: | Size: 120 KiB | 
| Before Width: | Height: | Size: 117 KiB | 
| @@ -1,657 +0,0 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <title>JSDoc: Global</title> | ||||
|  | ||||
|     <script src="scripts/prettify/prettify.js"> </script> | ||||
|     <script src="scripts/prettify/lang-css.js"> </script> | ||||
|     <!--[if lt IE 9]> | ||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> | ||||
|     <![endif]--> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|  | ||||
| <div id="main"> | ||||
|  | ||||
|     <h1 class="page-title">Global</h1> | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| <section> | ||||
|  | ||||
| <header> | ||||
|      | ||||
|         <h2></h2> | ||||
|          | ||||
|      | ||||
| </header> | ||||
|  | ||||
| <article> | ||||
|     <div class="container-overview"> | ||||
|      | ||||
|          | ||||
|  | ||||
|          | ||||
|  | ||||
|  | ||||
| <dl class="details"> | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
| </dl> | ||||
|  | ||||
|  | ||||
|          | ||||
|      | ||||
|     </div> | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|         <h3 class="subsection-title">Members</h3> | ||||
|  | ||||
|          | ||||
|              | ||||
| <h4 class="name" id="api"><span class="type-signature"></span>api<span class="type-signature"> :<a href="BackendScriptApi.html">BackendScriptApi</a></span></h4> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| <div class="description"> | ||||
|     An instance of the frontend api available globally. | ||||
| </div> | ||||
|  | ||||
|  | ||||
|  | ||||
|     <h5>Type:</h5> | ||||
|     <ul> | ||||
|         <li> | ||||
|              | ||||
| <span class="param-type"><a href="BackendScriptApi.html">BackendScriptApi</a></span> | ||||
|  | ||||
|  | ||||
|         </li> | ||||
|     </ul> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| <dl class="details"> | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|     <dt class="tag-source">Source:</dt> | ||||
|     <dd class="tag-source"><ul class="dummy"><li> | ||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line32">line 32</a> | ||||
|     </li></ul></dd> | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
| </dl> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|          | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|         <h3 class="subsection-title">Type Definitions</h3> | ||||
|  | ||||
|          | ||||
|                  | ||||
| <h4 class="name" id="AttributeType">AttributeType</h4> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| <div class="description"> | ||||
|     There are currently only two types of attributes, labels or relations. | ||||
| </div> | ||||
|  | ||||
|  | ||||
|  | ||||
|     <h5>Type:</h5> | ||||
|     <ul> | ||||
|         <li> | ||||
|              | ||||
| <span class="param-type">"label"</span> | ||||
| | | ||||
|  | ||||
| <span class="param-type">"relation"</span> | ||||
|  | ||||
|  | ||||
|         </li> | ||||
|     </ul> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| <dl class="details"> | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|     <dt class="tag-source">Source:</dt> | ||||
|     <dd class="tag-source"><ul class="dummy"><li> | ||||
|         <a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line11">line 11</a> | ||||
|     </li></ul></dd> | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
| </dl> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|              | ||||
|                  | ||||
| <h4 class="name" id="NotePathRecord">NotePathRecord</h4> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|     <h5>Type:</h5> | ||||
|     <ul> | ||||
|         <li> | ||||
|              | ||||
| <span class="param-type">Object</span> | ||||
|  | ||||
|  | ||||
|         </li> | ||||
|     </ul> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|     <h5 class="subsection-title">Properties:</h5> | ||||
|  | ||||
|      | ||||
|  | ||||
| <table class="props"> | ||||
|     <thead> | ||||
|     <tr> | ||||
|          | ||||
|         <th>Name</th> | ||||
|          | ||||
|  | ||||
|         <th>Type</th> | ||||
|  | ||||
|          | ||||
|  | ||||
|          | ||||
|  | ||||
|         <th class="last">Description</th> | ||||
|     </tr> | ||||
|     </thead> | ||||
|  | ||||
|     <tbody> | ||||
|      | ||||
|  | ||||
|         <tr> | ||||
|              | ||||
|                 <td class="name"><code>isArchived</code></td> | ||||
|              | ||||
|  | ||||
|             <td class="type"> | ||||
|              | ||||
|                  | ||||
| <span class="param-type">boolean</span> | ||||
|  | ||||
|  | ||||
|              | ||||
|             </td> | ||||
|  | ||||
|              | ||||
|  | ||||
|              | ||||
|  | ||||
|             <td class="description last"></td> | ||||
|         </tr> | ||||
|  | ||||
|      | ||||
|  | ||||
|         <tr> | ||||
|              | ||||
|                 <td class="name"><code>isInHoistedSubTree</code></td> | ||||
|              | ||||
|  | ||||
|             <td class="type"> | ||||
|              | ||||
|                  | ||||
| <span class="param-type">boolean</span> | ||||
|  | ||||
|  | ||||
|              | ||||
|             </td> | ||||
|  | ||||
|              | ||||
|  | ||||
|              | ||||
|  | ||||
|             <td class="description last"></td> | ||||
|         </tr> | ||||
|  | ||||
|      | ||||
|  | ||||
|         <tr> | ||||
|              | ||||
|                 <td class="name"><code>notePath</code></td> | ||||
|              | ||||
|  | ||||
|             <td class="type"> | ||||
|              | ||||
|                  | ||||
| <span class="param-type">Array.<string></span> | ||||
|  | ||||
|  | ||||
|              | ||||
|             </td> | ||||
|  | ||||
|              | ||||
|  | ||||
|              | ||||
|  | ||||
|             <td class="description last"></td> | ||||
|         </tr> | ||||
|  | ||||
|      | ||||
|  | ||||
|         <tr> | ||||
|              | ||||
|                 <td class="name"><code>isHidden</code></td> | ||||
|              | ||||
|  | ||||
|             <td class="type"> | ||||
|              | ||||
|                  | ||||
| <span class="param-type">boolean</span> | ||||
|  | ||||
|  | ||||
|              | ||||
|             </td> | ||||
|  | ||||
|              | ||||
|  | ||||
|              | ||||
|  | ||||
|             <td class="description last"></td> | ||||
|         </tr> | ||||
|  | ||||
|      | ||||
|     </tbody> | ||||
| </table> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| <dl class="details"> | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|     <dt class="tag-source">Source:</dt> | ||||
|     <dd class="tag-source"><ul class="dummy"><li> | ||||
|         <a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line27">line 27</a> | ||||
|     </li></ul></dd> | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
| </dl> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|              | ||||
|                  | ||||
| <h4 class="name" id="NoteType">NoteType</h4> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| <div class="description"> | ||||
|     There are many different Note types, some of which are entirely opaque to the | ||||
| end user. Those types should be used only for checking against, they are | ||||
| not for direct use. | ||||
| </div> | ||||
|  | ||||
|  | ||||
|  | ||||
|     <h5>Type:</h5> | ||||
|     <ul> | ||||
|         <li> | ||||
|              | ||||
| <span class="param-type">"file"</span> | ||||
| | | ||||
|  | ||||
| <span class="param-type">"image"</span> | ||||
| | | ||||
|  | ||||
| <span class="param-type">"search"</span> | ||||
| | | ||||
|  | ||||
| <span class="param-type">"noteMap"</span> | ||||
| | | ||||
|  | ||||
| <span class="param-type">"launcher"</span> | ||||
| | | ||||
|  | ||||
| <span class="param-type">"doc"</span> | ||||
| | | ||||
|  | ||||
| <span class="param-type">"contentWidget"</span> | ||||
| | | ||||
|  | ||||
| <span class="param-type">"text"</span> | ||||
| | | ||||
|  | ||||
| <span class="param-type">"relationMap"</span> | ||||
| | | ||||
|  | ||||
| <span class="param-type">"render"</span> | ||||
| | | ||||
|  | ||||
| <span class="param-type">"canvas"</span> | ||||
| | | ||||
|  | ||||
| <span class="param-type">"mermaid"</span> | ||||
| | | ||||
|  | ||||
| <span class="param-type">"book"</span> | ||||
| | | ||||
|  | ||||
| <span class="param-type">"webView"</span> | ||||
| | | ||||
|  | ||||
| <span class="param-type">"code"</span> | ||||
|  | ||||
|  | ||||
|         </li> | ||||
|     </ul> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| <dl class="details"> | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|     <dt class="tag-source">Source:</dt> | ||||
|     <dd class="tag-source"><ul class="dummy"><li> | ||||
|         <a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line20">line 20</a> | ||||
|     </li></ul></dd> | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
| </dl> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|              | ||||
|                  | ||||
| <h4 class="name" id="int">int</h4> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| <div class="description"> | ||||
|     A whole number | ||||
| </div> | ||||
|  | ||||
|  | ||||
|  | ||||
|     <h5>Type:</h5> | ||||
|     <ul> | ||||
|         <li> | ||||
|              | ||||
| <span class="param-type">number</span> | ||||
|  | ||||
|  | ||||
|         </li> | ||||
|     </ul> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| <dl class="details"> | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|     <dt class="tag-source">Source:</dt> | ||||
|     <dd class="tag-source"><ul class="dummy"><li> | ||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line27">line 27</a> | ||||
|     </li></ul></dd> | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
|  | ||||
|      | ||||
| </dl> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|              | ||||
|      | ||||
|  | ||||
|      | ||||
| </article> | ||||
|  | ||||
| </section> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| </div> | ||||
|  | ||||
| <nav> | ||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> | ||||
| </nav> | ||||
|  | ||||
| <br class="clear"> | ||||
|  | ||||
| <footer> | ||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> | ||||
| </footer> | ||||
|  | ||||
| <script> prettyPrint(); </script> | ||||
| <script src="scripts/linenumber.js"> </script> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										1
									
								
								docs/backend_api/hierarchy.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -1,65 +1,87 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <title>JSDoc: Home</title> | ||||
| <!DOCTYPE html><html class="default" lang="en" data-base="."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>trilium</title><meta name="description" content="Documentation for trilium"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="assets/style.css"/><link rel="stylesheet" href="assets/highlight.css"/><script defer src="assets/main.js"></script><script async src="assets/icons.js" id="tsd-icons-script"></script><script async src="assets/search.js" id="tsd-search-script"></script><script async src="assets/navigation.js" id="tsd-nav-script"></script><script async src="assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="index.html" class="title">trilium</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><h1>trilium</h1></div><div class="tsd-panel tsd-typography"><a id="triliumnext-notes" class="tsd-anchor"></a><h1 class="tsd-anchor-link">TriliumNext Notes<a href="#triliumnext-notes" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><p><img src="https://img.shields.io/docker/pulls/triliumnext/notes" alt="Docker Pulls"> <img src="https://img.shields.io/github/downloads/triliumnext/notes/total" alt="GitHub Downloads (all assets, all releases)"></p> | ||||
| <p><a href="media/README.md">English</a> | <a href="media/README-ZH_CN.md">Chinese</a> | <a href="media/README.ru.md">Russian</a> | <a href="media/README.ja.md">Japanese</a> | <a href="media/README.it.md">Italian</a> | <a href="media/README.es.md">Spanish</a></p> | ||||
| <p>TriliumNext Notes is an open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases.</p> | ||||
| <p>See <a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour" target="_blank" class="external">screenshots</a> for quick overview:</p> | ||||
| <p><a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a></p> | ||||
| <a id="⚠️-why-triliumnext" class="tsd-anchor"></a><h2 class="tsd-anchor-link">⚠️ Why TriliumNext?<a href="#⚠️-why-triliumnext" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p><a href="https://github.com/zadam/trilium/issues/4620" target="_blank" class="external">The original Trilium project is in maintenance mode</a></p> | ||||
| <a id="migrating-from-trilium" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Migrating from Trilium?<a href="#migrating-from-trilium" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>There are no special migration steps to migrate from a zadam/Trilium instance to a TriliumNext/Notes instance. Just upgrade your Trilium instance to the latest version and <a href="#-installation">install TriliumNext/Notes as usual</a></p> | ||||
| <p>Versions up to and including <a href="https://github.com/TriliumNext/Notes/releases/tag/v0.90.4" target="_blank" class="external">v0.90.4</a> are compatible with the latest zadam/trilium version of <a href="https://github.com/zadam/trilium/releases/tag/v0.63.7" target="_blank" class="external">v0.63.7</a>. Any later versions of TriliumNext have their sync versions incremented.</p> | ||||
| <a id="💬-discuss-with-us" class="tsd-anchor"></a><h2 class="tsd-anchor-link">💬 Discuss with us<a href="#💬-discuss-with-us" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Feel free to join our official conversations. We would love to hear what features, suggestions, or issues you may have!</p> | ||||
| <ul> | ||||
| <li><a href="https://matrix.to/#/#triliumnext:matrix.org" target="_blank" class="external">Matrix</a> (For synchronous discussions) | ||||
| <ul> | ||||
| <li>The <code>General</code> Matrix room is also bridged to <a href="xmpp:discuss@trilium.thisgreat.party?join">XMPP</a></li> | ||||
| </ul> | ||||
| </li> | ||||
| <li><a href="https://github.com/TriliumNext/Notes/discussions" target="_blank" class="external">Github Discussions</a> (For Asynchronous discussions)</li> | ||||
| <li><a href="https://triliumnext.github.io/Docs/" target="_blank" class="external">Wiki</a> (For common how-to questions and user guides)</li> | ||||
| </ul> | ||||
| <a id="🎁-features" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🎁 Features<a href="#🎁-features" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><ul> | ||||
| <li>Notes can be arranged into arbitrarily deep tree. Single note can be placed into multiple places in the tree (see <a href="https://triliumnext.github.io/Docs/Wiki/cloning-notes" target="_blank" class="external">cloning</a>)</li> | ||||
| <li>Rich WYSIWYG note editing including e.g. tables, images and <a href="https://triliumnext.github.io/Docs/Wiki/text-notes" target="_blank" class="external">math</a> with markdown <a href="https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat" target="_blank" class="external">autoformat</a></li> | ||||
| <li>Support for editing <a href="https://triliumnext.github.io/Docs/Wiki/code-notes" target="_blank" class="external">notes with source code</a>, including syntax highlighting</li> | ||||
| <li>Fast and easy <a href="https://triliumnext.github.io/Docs/Wiki/note-navigation" target="_blank" class="external">navigation between notes</a>, full text search and <a href="https://triliumnext.github.io/Docs/Wiki/note-hoisting" target="_blank" class="external">note hoisting</a></li> | ||||
| <li>Seamless <a href="https://triliumnext.github.io/Docs/Wiki/note-revisions" target="_blank" class="external">note versioning</a></li> | ||||
| <li>Note <a href="https://triliumnext.github.io/Docs/Wiki/attributes" target="_blank" class="external">attributes</a> can be used for note organization, querying and advanced <a href="https://triliumnext.github.io/Docs/Wiki/scripts" target="_blank" class="external">scripting</a></li> | ||||
| <li><a href="https://triliumnext.github.io/Docs/Wiki/synchronization" target="_blank" class="external">Synchronization</a> with self-hosted sync server | ||||
| <ul> | ||||
| <li>there's a <a href="https://trilium.cc/paid-hosting" target="_blank" class="external">3rd party service for hosting synchronisation server</a></li> | ||||
| </ul> | ||||
| </li> | ||||
| <li><a href="https://triliumnext.github.io/Docs/Wiki/sharing" target="_blank" class="external">Sharing</a> (publishing) notes to public internet</li> | ||||
| <li>Strong <a href="https://triliumnext.github.io/Docs/Wiki/protected-notes" target="_blank" class="external">note encryption</a> with per-note granularity</li> | ||||
| <li>Sketching diagrams with built-in Excalidraw (note type "canvas")</li> | ||||
| <li><a href="https://triliumnext.github.io/Docs/Wiki/relation-map" target="_blank" class="external">Relation maps</a> and <a href="https://triliumnext.github.io/Docs/Wiki/link-map" target="_blank" class="external">link maps</a> for visualizing notes and their relations</li> | ||||
| <li><a href="https://triliumnext.github.io/Docs/Wiki/scripts" target="_blank" class="external">Scripting</a> - see <a href="https://triliumnext.github.io/Docs/Wiki/advanced-showcases" target="_blank" class="external">Advanced showcases</a></li> | ||||
| <li><a href="https://triliumnext.github.io/Docs/Wiki/etapi" target="_blank" class="external">REST API</a> for automation</li> | ||||
| <li>Scales well in both usability and performance upwards of 100 000 notes</li> | ||||
| <li>Touch optimized <a href="https://triliumnext.github.io/Docs/Wiki/mobile-frontend" target="_blank" class="external">mobile frontend</a> for smartphones and tablets</li> | ||||
| <li><a href="https://triliumnext.github.io/Docs/Wiki/themes" target="_blank" class="external">Night theme</a></li> | ||||
| <li><a href="https://triliumnext.github.io/Docs/Wiki/evernote-import" target="_blank" class="external">Evernote</a> and <a href="https://triliumnext.github.io/Docs/Wiki/markdown" target="_blank" class="external">Markdown import & export</a></li> | ||||
| <li><a href="https://triliumnext.github.io/Docs/Wiki/web-clipper" target="_blank" class="external">Web Clipper</a> for easy saving of web content</li> | ||||
| </ul> | ||||
| <p>✨ Check out the following third-party resources/communities for more TriliumNext related goodies:</p> | ||||
| <ul> | ||||
| <li><a href="https://github.com/Nriver/awesome-trilium" target="_blank" class="external">awesome-trilium</a> for 3rd party themes, scripts, plugins and more.</li> | ||||
| <li><a href="https://trilium.rocks/" target="_blank" class="external">TriliumRocks!</a> for tutorials, guides, and much more.</li> | ||||
| </ul> | ||||
| <a id="🏗-installation" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🏗 Installation<a href="#🏗-installation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="desktop" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Desktop<a href="#desktop" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>To use TriliumNext on your desktop machine (Linux, MacOS, and Windows) you have a few options:</p> | ||||
| <ul> | ||||
| <li>Download the binary release for your platform from the <a href="https://github.com/TriliumNext/Notes/releases/latest" target="_blank" class="external">latest release page</a>, unzip the package and run the <code>trilium</code> executable.</li> | ||||
| <li>Access TriliumNext via the web interface of a server installation (see below) | ||||
| <ul> | ||||
| <li>Currently only the latest versions of Chrome & Firefox are supported (and tested).</li> | ||||
| </ul> | ||||
| </li> | ||||
| <li>(Coming Soon) TriliumNext will also be provided as a Flatpak</li> | ||||
| </ul> | ||||
| <a id="macos" class="tsd-anchor"></a><h4 class="tsd-anchor-link">MacOS<a href="#macos" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><p>Currently when running TriliumNext/Notes on MacOS, you may get the following error:</p> | ||||
| <blockquote> | ||||
| <p>Apple could not verify "TriliumNext Notes" is free of malware and may harm your Mac or compromise your privacy.</p> | ||||
| </blockquote> | ||||
| <p>You will need to run the command on your shell to resolve the error (documented <a href="https://github.com/TriliumNext/Notes/issues/329#issuecomment-2287164137" target="_blank" class="external">here</a>):</p> | ||||
| <pre><code class="bash"><span class="hl-0">xattr</span><span class="hl-1"> </span><span class="hl-2">-c</span><span class="hl-1"> </span><span class="hl-3">"/path/to/Trilium Next.app"</span> | ||||
| </code><button type="button">Copy</button></pre> | ||||
|  | ||||
|     <script src="scripts/prettify/prettify.js"> </script> | ||||
|     <script src="scripts/prettify/lang-css.js"> </script> | ||||
|     <!--[if lt IE 9]> | ||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> | ||||
|     <![endif]--> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | ||||
| </head> | ||||
| <a id="mobile" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Mobile<a href="#mobile" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>To use TriliumNext on a mobile device:</p> | ||||
| <ul> | ||||
| <li>Use a mobile web browser to access the mobile interface of a server installation (see below)</li> | ||||
| <li>Use of a mobile app is not yet supported (<a href="https://github.com/TriliumNext/Notes/issues/72" target="_blank" class="external">see here</a>) to track mobile improvements.</li> | ||||
| </ul> | ||||
| <a id="server" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Server<a href="#server" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>To install TriliumNext on your own server (including via Docker from <a href="https://hub.docker.com/r/triliumnext/notes" target="_blank" class="external">Dockerhub</a>) follow <a href="https://triliumnext.github.io/Docs/Wiki/server-installation" target="_blank" class="external">the server installation docs</a>.</p> | ||||
| <a id="📝-documentation" class="tsd-anchor"></a><h2 class="tsd-anchor-link">📝 Documentation<a href="#📝-documentation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p><a href="https://triliumnext.github.io/Docs" target="_blank" class="external">See wiki for complete list of documentation pages.</a></p> | ||||
| <p>You can also read <a href="https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge" target="_blank" class="external">Patterns of personal knowledge base</a> to get some inspiration on how you might use TriliumNext.</p> | ||||
| <a id="💻-contribute" class="tsd-anchor"></a><h2 class="tsd-anchor-link">💻 Contribute<a href="#💻-contribute" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="code" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Code<a href="#code" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="shell"><span class="hl-0">git</span><span class="hl-1"> </span><span class="hl-3">clone</span><span class="hl-1"> </span><span class="hl-3">https://github.com/TriliumNext/Notes.git</span><br/><span class="hl-0">cd</span><span class="hl-1"> </span><span class="hl-3">Notes</span><br/><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-3">install</span><br/><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-3">run</span><span class="hl-1"> </span><span class="hl-3">start-server</span> | ||||
| </code><button type="button">Copy</button></pre> | ||||
|  | ||||
| <body> | ||||
|  | ||||
| <div id="main"> | ||||
|  | ||||
|     <h1 class="page-title">Home</h1> | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
|     <h3> </h3> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| </div> | ||||
|  | ||||
| <nav> | ||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> | ||||
| </nav> | ||||
|  | ||||
| <br class="clear"> | ||||
|  | ||||
| <footer> | ||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> | ||||
| </footer> | ||||
|  | ||||
| <script> prettyPrint(); </script> | ||||
| <script src="scripts/linenumber.js"> </script> | ||||
| </body> | ||||
| </html> | ||||
| <a id="documentation" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Documentation<a href="#documentation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Head on over to our <a href="https://github.com/TriliumNext/Docs" target="_blank" class="external">Docs repo</a></p> | ||||
| <a id="👏-shoutouts" class="tsd-anchor"></a><h2 class="tsd-anchor-link">👏 Shoutouts<a href="#👏-shoutouts" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><ul> | ||||
| <li><a href="https://github.com/ckeditor/ckeditor5" target="_blank" class="external">CKEditor 5</a> - best WYSIWYG editor on the market, very interactive and listening team</li> | ||||
| <li><a href="https://github.com/mar10/fancytree" target="_blank" class="external">FancyTree</a> - very feature rich tree library without real competition. TriliumNext Notes would not be the same without it.</li> | ||||
| <li><a href="https://github.com/codemirror/CodeMirror" target="_blank" class="external">CodeMirror</a> - code editor with support for huge amount of languages</li> | ||||
| <li><a href="https://github.com/jsplumb/jsplumb" target="_blank" class="external">jsPlumb</a> - visual connectivity library without competition. Used in <a href="https://triliumnext.github.io/Docs/Wiki/relation-map.html" target="_blank" class="external">relation maps</a> and <a href="https://triliumnext.github.io/Docs/Wiki/note-map.html#link-map" target="_blank" class="external">link maps</a></li> | ||||
| </ul> | ||||
| <a id="🤝-support" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🤝 Support<a href="#🤝-support" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>You can support the original Trilium developer using GitHub Sponsors, <a href="https://paypal.me/za4am" target="_blank" class="external">PayPal</a> or Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). | ||||
| Support for the TriliumNext organization will be possible in the near future.</p> | ||||
| <a id="🔑-license" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🔑 License<a href="#🔑-license" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.</p> | ||||
| </div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#triliumnext-notes"><span>Trilium<wbr/>Next <wbr/>Notes</span></a><ul><li><a href="#⚠️-why-triliumnext"><span>⚠️ <wbr/>Why <wbr/>Trilium<wbr/>Next?</span></a></li><li><ul><li><a href="#migrating-from-trilium"><span>Migrating from <wbr/>Trilium?</span></a></li></ul></li><li><a href="#💬-discuss-with-us"><span>💬 <wbr/>Discuss with us</span></a></li><li><a href="#🎁-features"><span>🎁 <wbr/>Features</span></a></li><li><a href="#🏗-installation"><span>🏗 <wbr/>Installation</span></a></li><li><ul><li><a href="#desktop"><span>Desktop</span></a></li><li><ul><li><a href="#macos"><span>MacOS</span></a></li></ul></li><li><a href="#mobile"><span>Mobile</span></a></li><li><a href="#server"><span>Server</span></a></li></ul></li><li><a href="#📝-documentation"><span>📝 <wbr/>Documentation</span></a></li><li><a href="#💻-contribute"><span>💻 <wbr/>Contribute</span></a></li><li><ul><li><a href="#code"><span>Code</span></a></li><li><a href="#documentation"><span>Documentation</span></a></li></ul></li><li><a href="#👏-shoutouts"><span>👏 <wbr/>Shoutouts</span></a></li><li><a href="#🤝-support"><span>🤝 <wbr/>Support</span></a></li><li><a href="#🔑-license"><span>🔑 <wbr/>License</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html">trilium</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html> | ||||
|   | ||||
							
								
								
									
										14
									
								
								docs/backend_api/interfaces/becca_entities_rows.NoteRow.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,11 @@ | ||||
| <!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>OptionRow | trilium</title><meta name="description" content="Documentation for trilium"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">trilium</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">trilium</a></li><li><a href="../modules/becca_entities_rows.html">becca/entities/rows</a></li><li><a href="becca_entities_rows.OptionRow.html">OptionRow</a></li></ul><h1>Interface OptionRow</h1></div><section class="tsd-panel tsd-comment"><div class="tsd-comment tsd-typography"><p>Database representation of an option.</p> | ||||
| <p>Options are key-value pairs that are used to store information such as user preferences (for example | ||||
| the current theme, sync server information), but also information about the state of the application).</p> | ||||
| </div><div class="tsd-comment tsd-typography"></div></section><div class="tsd-signature"><span class="tsd-signature-keyword">interface</span> <span class="tsd-kind-interface">OptionRow</span> <span class="tsd-signature-symbol">{</span><br/>    <a class="tsd-kind-property" href="becca_entities_rows.OptionRow.html#issynced">isSynced</a><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="becca_entities_rows.OptionRow.html#name">name</a><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="becca_entities_rows.OptionRow.html#utcdatemodified">utcDateModified</a><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="becca_entities_rows.OptionRow.html#value">value</a><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">;</span><br/><span class="tsd-signature-symbol">}</span></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/TriliumNext/Notes/blob/6bbff3efd82eb36b9060d60252c90ff358651405/src/becca/entities/rows.ts#L47">becca/entities/rows.ts:47</a></li></ul></aside><section class="tsd-panel-group tsd-index-group"><section class="tsd-panel tsd-index-panel"><details class="tsd-index-content tsd-accordion" open><summary class="tsd-accordion-summary tsd-index-summary"><h5 class="tsd-index-heading uppercase" role="button" aria-expanded="false" tabIndex="0"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-chevronSmall"></use></svg> Index</h5></summary><div class="tsd-accordion-details"><section class="tsd-index-section"><h3 class="tsd-index-heading">Properties</h3><div class="tsd-index-list"><a href="becca_entities_rows.OptionRow.html#issynced" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>is<wbr/>Synced</span></a> | ||||
| <a href="becca_entities_rows.OptionRow.html#name" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>name</span></a> | ||||
| <a href="becca_entities_rows.OptionRow.html#utcdatemodified" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>utc<wbr/>Date<wbr/>Modified?</span></a> | ||||
| <a href="becca_entities_rows.OptionRow.html#value" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>value</span></a> | ||||
| </div></section></div></details></section></section><details class="tsd-panel-group tsd-member-group tsd-accordion" open><summary class="tsd-accordion-summary" data-key="section-Properties"><h2><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg> Properties</h2></summary><section><section class="tsd-panel tsd-member"><a id="issynced" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>is<wbr/>Synced</span><a href="#issynced" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">isSynced</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span></div><div class="tsd-comment tsd-typography"><p><code>true</code> if the value should be synced across multiple instances (e.g. locale) or <code>false</code> if it should be local-only (e.g. theme).</p> | ||||
| </div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/TriliumNext/Notes/blob/6bbff3efd82eb36b9060d60252c90ff358651405/src/becca/entities/rows.ts#L53">becca/entities/rows.ts:53</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="name" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>name</span><a href="#name" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">name</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span></div><div class="tsd-comment tsd-typography"><p>The name of the option.</p> | ||||
| </div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/TriliumNext/Notes/blob/6bbff3efd82eb36b9060d60252c90ff358651405/src/becca/entities/rows.ts#L49">becca/entities/rows.ts:49</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="utcdatemodified" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><code class="tsd-tag">Optional</code><span>utc<wbr/>Date<wbr/>Modified</span><a href="#utcdatemodified" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">utcDateModified</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">string</span></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/TriliumNext/Notes/blob/6bbff3efd82eb36b9060d60252c90ff358651405/src/becca/entities/rows.ts#L54">becca/entities/rows.ts:54</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="value" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>value</span><a href="#value" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">value</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span></div><div class="tsd-comment tsd-typography"><p>The value of the option.</p> | ||||
| </div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/TriliumNext/Notes/blob/6bbff3efd82eb36b9060d60252c90ff358651405/src/becca/entities/rows.ts#L51">becca/entities/rows.ts:51</a></li></ul></aside></section></section></details></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Properties"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Properties</summary><div><a href="#issynced" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>is<wbr/>Synced</span></a><a href="#name" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>name</span></a><a href="#utcdatemodified" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>utc<wbr/>Date<wbr/>Modified</span></a><a href="#value" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>value</span></a></div></details></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">trilium</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html> | ||||
							
								
								
									
										97
									
								
								docs/backend_api/media/README-ZH_CN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,97 @@ | ||||
| # TriliumNext Notes | ||||
|  | ||||
| [English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) | ||||
|  | ||||
| TriliumNext Notes 是一个层次化的笔记应用程序,专注于建立大型个人知识库。请参阅[屏幕截图](https://triliumnext.github.io/Docs/Wiki/screenshot-tour)以快速了解: | ||||
|  | ||||
| <a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a> | ||||
|  | ||||
| ## ⚠️ 为什么选择TriliumNext? | ||||
|  | ||||
| [原始的Trilium项目目前处于维护模式](https://github.com/zadam/trilium/issues/4620) | ||||
|  | ||||
| ## 🗭 与我们讨论 | ||||
|  | ||||
| 欢迎加入我们的官方讨论和社区。我们专注于Trilium的开发,乐于听取您对功能、建议或问题的意见! | ||||
|  | ||||
| - [Matrix](https://matrix.to/#/#triliumnext:matrix.org)(用于同步讨论) | ||||
| - [Github Discussions](https://github.com/TriliumNext/Notes/discussions)(用于异步讨论) | ||||
| - [Wiki](https://triliumnext.github.io/Docs/)(用于常见操作问题和用户指南) | ||||
|  | ||||
| 上面链接的两个房间是镜像的,所以您可以在任意平台上使用XMPP或者Matrix来和我们交流。 | ||||
|  | ||||
| ### 非官方社区 | ||||
|  | ||||
| [Trilium Rocks](https://discord.gg/aqdX9mXX4r) | ||||
|  | ||||
| ## 🎁 特性 | ||||
|  | ||||
| * 笔记可以排列成任意深的树。单个笔记可以放在树中的多个位置(请参阅[克隆](https://triliumnext.github.io/Docs/Wiki/cloning-notes)) | ||||
| * 丰富的所见即所得笔记编辑功能,包括带有 Markdown [自动格式化功能的](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)表格,图像和[数学公式](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support) | ||||
| * 支持编辑[使用源代码的笔记](https://triliumnext.github.io/Docs/Wiki/code-notes),包括语法高亮显示 | ||||
| * 笔记之间快速[导航](https://triliumnext.github.io/Docs/Wiki/note-navigation),全文搜索和[提升笔记](https://triliumnext.github.io/Docs/Wiki/note-hoisting) | ||||
| * 无缝[笔记版本控制](https://triliumnext.github.io/Docs/Wiki/note-revisions) | ||||
| * 笔记[属性](https://triliumnext.github.io/Docs/Wiki/attributes)可用于笔记组织,查询和高级[脚本编写](https://triliumnext.github.io/Docs/Wiki/scripts) | ||||
| * [同步](https://triliumnext.github.io/Docs/Wiki/synchronization)与自托管同步服务器 | ||||
|   * 有一个[第三方提供的同步服务器托管服务](https://trilium.cc/paid-hosting) | ||||
| * 公开地[分享](https://triliumnext.github.io/Docs/Wiki/sharing)(发布)笔记到互联网 | ||||
| * 具有按笔记粒度的强大的[笔记加密](https://triliumnext.github.io/Docs/Wiki/protected-notes) | ||||
| * 使用自带的 Excalidraw 来绘制图表(笔记类型“画布”) | ||||
| * [关系图](https://triliumnext.github.io/Docs/Wiki/relation-map)和[链接图](https://triliumnext.github.io/Docs/Wiki/link-map),用于可视化笔记及其关系 | ||||
| * [脚本](https://triliumnext.github.io/Docs/Wiki/scripts) - 请参阅[高级功能展示](https://triliumnext.github.io/Docs/Wiki/advanced-showcases) | ||||
| * 可用于自动化的 [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) | ||||
| * 在拥有超过 10 万条笔记时仍能保持良好的可用性和性能 | ||||
| * 针对智能手机和平板电脑进行优化的[用于移动设备的前端](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) | ||||
| * [夜间主题](https://triliumnext.github.io/Docs/Wiki/themes) | ||||
| * [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) 和 [Markdown 导入导出](https://triliumnext.github.io/Docs/Wiki/markdown)功能 | ||||
| * 使用[网页剪藏](https://triliumnext.github.io/Docs/Wiki/web-clipper)轻松保存互联网上的内容 | ||||
|  | ||||
| ✨ 查看以下第三方资源,获取更多关于TriliumNext的好东西: | ||||
|  | ||||
| - [awesome-trilium](https://github.com/Nriver/awesome-trilium):提供第三方主题、脚本、插件等资源的列表。 | ||||
| - [TriliumRocks!](https://trilium.rocks/):提供教程、指南等更多内容。 | ||||
|  | ||||
| ## 🏗 构建 | ||||
|  | ||||
| Trilium 可以用作桌面应用程序(Linux 和 Windows)或服务器(Linux)上托管的 Web 应用程序。虽然有 macOS 版本的桌面应用程序,但它[不受支持](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support)。 | ||||
|  | ||||
| * 如果要在桌面上使用 Trilium,请从[最新版本](https://github.com/TriliumNext/Notes/releases/latest)下载适用于您平台的二进制版本,解压缩该软件包并运行`trilium`可执行文件。 | ||||
| * 如果要在服务器上安装 Trilium,请参考[此页面](https://triliumnext.github.io/Docs/Wiki/server-installation)。 | ||||
|   * 当前仅支持(测试过)最近发布的 Chrome 和 Firefox 浏览器。 | ||||
|  | ||||
| Trilium 也提供 Flatpak: | ||||
|  | ||||
| [<img width="240" src="https://flathub.org/assets/badges/flathub-badge-en.png">](https://flathub.org/apps/details/com.github.zadam.trilium) | ||||
|  | ||||
| ## 📝 文档 | ||||
|  | ||||
| [有关文档页面的完整列表,请参见 Wiki。](https://triliumnext.github.io/Docs/) | ||||
|  | ||||
| * [Wiki 的中文翻译版本](https://github.com/baddate/trilium/wiki/) | ||||
|  | ||||
| 您还可以阅读[个人知识库模式](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge),以获取有关如何使用 Trilium 的灵感。 | ||||
|  | ||||
| ## 💻 贡献 | ||||
|  | ||||
|  | ||||
| 或者克隆本仓库到本地,并运行 | ||||
|  | ||||
| ```shell | ||||
| npm install | ||||
| npm run start-server | ||||
| ``` | ||||
|  | ||||
| ## 👏 致谢 | ||||
|  | ||||
| * [CKEditor 5](https://github.com/ckeditor/ckeditor5) - 市面上最好的所见即所得编辑器,拥有互动性强且聆听能力强的团队 | ||||
| * [FancyTree](https://github.com/mar10/fancytree) - 一个非常丰富的关于树的库,强大到没有对手。没有它,Trilium Notes 将不会如此。 | ||||
| * [CodeMirror](https://github.com/codemirror/CodeMirror) - 支持大量语言的代码编辑器 | ||||
| * [jsPlumb](https://github.com/jsplumb/jsplumb) - 强大的可视化连接库。用于[关系图](https://triliumnext.github.io/Docs/Wiki/relation-map)和[链接图](https://triliumnext.github.io/Docs/Wiki/link-map) | ||||
|  | ||||
| ## 🤝 捐赠 | ||||
|  | ||||
| 你可以通过 GitHub Sponsors,[PayPal](https://paypal.me/za4am) 或者比特币 (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2) 来捐赠。 | ||||
|  | ||||
| ## 🔑 许可证 | ||||
|  | ||||
| 本程序是自由软件:你可以再发布本软件和/或修改本软件,只要你遵循 Free Software Foundation 发布的 GNU Affero General Public License 的第三版或者任何(由你选择)更晚的版本。 | ||||
							
								
								
									
										106
									
								
								docs/backend_api/media/README.es.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,106 @@ | ||||
| # TriliumNext Notes | ||||
|  | ||||
| [English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) | ||||
|  | ||||
| TriliumNext Notes es una aplicación de toma de notas jerárquicas multi-plataforma y de código libre con un enfoque en la construcción de grandes bases de conocimiento personal. | ||||
|  | ||||
| Vea estas [capturas de pantalla](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) para un vistazo rápido: | ||||
|  | ||||
| <a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a> | ||||
|  | ||||
| ## ⚠️ ¿Por qué usar TriliumNext? | ||||
|  | ||||
| [El proyecto Trilium original está en modo de mantenimiento](https://github.com/zadam/trilium/issues/4620) | ||||
|  | ||||
| ### ¿Cómo migrar desde Trilium? | ||||
|  | ||||
| No hay pasos de migración especiales para migrar de una instancia de zadam/Trilium a una instancia de TriliumNext/Notes. Simplemente actualice su instancia de Trilium a la última versión e [instale TriliumNext/Notes como de costumbre](#-Instalación) | ||||
|  | ||||
| ## 💬 Discuta con nosotros | ||||
|  | ||||
| Siéntase libre de unirse a nuestras conversaciones oficiales. ¡Nos encantaría escuchar de las características, sugerencias o problemas que pueda tener! | ||||
|  | ||||
| - [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (Para discusiones síncronas) | ||||
|   - La sala `General` es replicada a [XMPP](xmpp:discuss@trilium.thisgreat.party?join) | ||||
| - [Discusiones de GitHub](https://github.com/TriliumNext/Notes/discussions) (Para discusiones asíncronas) | ||||
| - [Wiki](https://triliumnext.github.io/Docs/) (Para preguntas frecuentes y guías de usuario) | ||||
|  | ||||
| ## 🎁 Características | ||||
|  | ||||
| - Las notas pueden ser acomodadas en un árbol de profundidad arbitraria. Una sola nota puede ser colocada en múltiples lugares del árbol (vea [clonar](https://triliumnext.github.io/Docs/Wiki/cloning-notes) | ||||
| - Edición de notas WYSIWYG enriquecida que incluye, por ejemplo, tablas, imágenes y [matemáticas](https://triliumnext.github.io/Docs/Wiki/text-notes) con [autoformato](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat) markdown | ||||
| - Soporte para editar [notas con código fuente](https://triliumnext.github.io/Docs/Wiki/code-notes), incluyendo resaltado de sintaxis | ||||
| - Rápida y sencilla [navegación entre notas](https://triliumnext.github.io/Docs/Wiki/note-navigation), búsqueda de texto completo y [elevación de notas](https://triliumnext.github.io/Docs/Wiki/note-hoisting) | ||||
| - [Versionado de notas](https://triliumnext.github.io/Docs/Wiki/note-revisions) sutil | ||||
| - Los [atributos](https://triliumnext.github.io/Docs/Wiki/attributes) de las notas pueden utilizarse para organización, realizar consultas y [scripts](https://triliumnext.github.io/Docs/Wiki/scripts) avanzados | ||||
| - [Sincronización](https://triliumnext.github.io/Docs/Wiki/synchronization) con servidor de sincronización propio | ||||
|   - existe un [servicio de terceros para alojar el servidor de sincronización](https://trilium.cc/paid-hosting) | ||||
| - [Compartir](https://triliumnext.github.io/Docs/Wiki/sharing) (publicar) notas al Internet público | ||||
| - Fuerte [encriptación de notas](https://triliumnext.github.io/Docs/Wiki/protected-notes) con granularidad para cada nota | ||||
| - Esbozo de diagramas con Excalidraw incorporado (tipo de nota «canvas») | ||||
| - [Mapas de relaciones](<https://triliumnext.github.io/Docs/Wiki/relation-map>) y [mapas de enlaces](https://triliumnext.github.io/Docs/Wiki/link-map) para visualizar las notas y sus relaciones | ||||
| - [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - vea [casos de uso avanzados](https://triliumnext.github.io/Docs/Wiki/advanced-showcases) | ||||
| - [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) para automatización | ||||
| - Escala bien tanto en uso como en rendimiento a partir de 100,000 notas | ||||
| - [Interfaz móvil](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) optimizada para teléfonos inteligentes y tabletas | ||||
| - [Tema nocturno](https://triliumnext.github.io/Docs/Wiki/themes) | ||||
| - Importación y exportación de [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) y [Markdown](https://triliumnext.github.io/Docs/Wiki/markdown) | ||||
| - [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) para guardar fácilmente contenido web | ||||
|  | ||||
| ✨ Consulte los/las siguientes recursos/comunidades de terceros para obtener más información sobre complementos para TriliumNext: | ||||
|  | ||||
| - [awesome-trilium](https://github.com/Nriver/awesome-trilium) para temas, scripts, plugins y más de terceros. | ||||
| - [TriliumRocks!](https://trilium.rocks/) para tutoriales, guías y mucho más. | ||||
|  | ||||
| ## 🏗 Instalación | ||||
|  | ||||
| ### Escritorio | ||||
|  | ||||
| Para usar TriliumNext en su máquina de escritorio (Linux, MacOS y Windows) tiene algunas opciones: | ||||
|  | ||||
| - Descargue la versión binaria para su plataforma desde la [página de lanzamientos](https://github.com/TriliumNext/Notes/releases/latest), descomprima el paquete y ejecute el ejecutable `trilium`. | ||||
| - Acceda a TriliumNext a través de la interfaz web de una instalación de servidor (ver más abajo) | ||||
|   - Actualmente solo las últimas versiones de Chrome y Firefox son compatibles (y están probadas). | ||||
| - (Próximamente) TriliumNext también se proporcionará como un Flatpak | ||||
|  | ||||
| ### Móvil | ||||
|  | ||||
| Para usar TriliumNext en un dispositivo móvil: | ||||
|  | ||||
| - Utilice un navegador web móvil para acceder a la interfaz móvil de una instalación de servidor (ver más abajo) | ||||
| - El uso de una aplicación móvil aún no está soportado ([vea aquí](https://github.com/TriliumNext/Notes/issues/72)) para seguir las mejoras móviles. | ||||
|  | ||||
| ### Servidor | ||||
|  | ||||
| Para instalar TriliumNext en su servidor (incluyendo vía Docker desde [Dockerhub](https://hub.docker.com/r/triliumnext/notes)) siga la [documentación de instalación de servidor](https://triliumnext.github.io/Docs/Wiki/server-installation). | ||||
|  | ||||
| ## 📝 Documentación | ||||
|  | ||||
| [Vea la Wiki para la lista completa de páginas de documentación.](https://triliumnext.github.io/Docs) | ||||
|  | ||||
| También puede leer [Patrones para una base de conocimiento personal](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge) para obtener un poco de inspiración de como podría usar TriliumNext. | ||||
|  | ||||
| ## 💻 Contribuir | ||||
|  | ||||
| Clone localmente y ejecute | ||||
|  | ||||
| ```shell | ||||
| npm install | ||||
| npm run start-server | ||||
| ``` | ||||
|  | ||||
| ## 👏 Reconocimientos | ||||
|  | ||||
| - [CKEditor 5](https://github.com/ckeditor/ckeditor5) - el mejor editor WYSIWYG en el mercado, equipo muy interactivo y atento | ||||
| - [FancyTree](https://github.com/mar10/fancytree) - biblioteca de árbol muy rica en funciones sin competencia real. TriliumNext Notes no sería lo mismo sin esta. | ||||
| - [CodeMirror](https://github.com/codemirror/CodeMirror) - editor de código con soporte para una gran cantidad de lenguajes | ||||
| - [jsPlumb](https://github.com/jsplumb/jsplumb) - biblioteca de conectividad visual sin competencia. Usado en [mapas de relación](https://triliumnext.github.io/Docs/Wiki/Relation-map) y [mapas de enlace](https://triliumnext.github.io/Docs/Wiki/Link-map) | ||||
|  | ||||
| ## 🤝 Soporte | ||||
|  | ||||
| Puede apoyar al desarrollador original de Trilium usando GitHub Sponsors, [PayPal](https://paypal.me/za4am) o Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). | ||||
| Apoyo para la organización TriliumNext será posible en un futuro próximo. | ||||
|  | ||||
| ## 🔑 Licencia | ||||
|  | ||||
| Este programa es software libre: puede redistribuirlo y/o modificarlo bajo los términos de la Licencia Pública General de Affero GNU publicada por la Free Software Foundation, ya sea la versión 3 de la Licencia, o (a su elección) cualquier versión posterior. | ||||
							
								
								
									
										93
									
								
								docs/backend_api/media/README.it.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,93 @@ | ||||
| # TriliumNext Notes | ||||
|  | ||||
| [English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) | ||||
|  | ||||
| TriliumNext Notes è un'applicazione per appunti ad organizzazione gerarchica, studiata per la costruzione di archivi di conoscenza personali di grandi dimensioni. | ||||
|  | ||||
| Vedi [fotografie](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) per una panoramica veloce: | ||||
|  | ||||
| <a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a> | ||||
|  | ||||
| ## ⚠️ Perchè TriliumNext? | ||||
| [Il progetto originale Trilium è in modalità di manutenzione](https://github.com/zadam/trilium/issues/4620) | ||||
|  | ||||
| ## 🗭 Discuti con noi | ||||
| Sentiti libero di unirti alle nostre discussioni ufficiali e alla nostra comunità. Siamo concentrati sullo sviluppo di Trilium e ci piacerebbe sapere quali funzioni, suggerimenti o eventuali problemi hai! | ||||
|  | ||||
| - [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (Per discussioni sincrone) | ||||
| - [Discussioni Github](https://github.com/TriliumNext/Notes/discussions) (Per discussioni asincrone) | ||||
| - [Wiki](https://triliumnext.github.io/Docs/) (Per le domande più comuni e le guide per l'utente) | ||||
|  | ||||
| Le due stanze linkate sopra sono connesse e contengono gli stessi messaggi, quindi puoi usare XMPP o Matrix da qualsiasi client tu preferisca, praticamente su qualsiasi piattaforma! | ||||
| ### Comunità non ufficiali | ||||
|  | ||||
| [Trilium Rocks](https://discord.gg/aqdX9mXX4r) | ||||
| ## 🎁 Funzionalità | ||||
|  | ||||
| * Gli appunti possono essere organizzati in un albero di profondità arbitraria. Un singolo appunto può essere collocato in più posti nell'albero (vedi [clonazione](https://triliumnext.github.io/Docs/Wiki/cloning-notes)) | ||||
| * Ricco editor visuale (WYSIWYG), con supporto -tra l'altro- per tabelle, immagini ed [espressioni matematiche](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support) e con [formattazione automatica](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat) per markdown | ||||
| * Supporto per la modifica di [appunti con codice sorgente](https://triliumnext.github.io/Docs/Wiki/code-notes), con evidenziazione della sintassi | ||||
| * [Navigazione veloce](https://triliumnext.github.io/Docs/Wiki/note-navigation) tra gli appunti, ricerca testuale completa e [fissaggio degli appunti](https://triliumnext.github.io/Docs/Wiki/note-hoisting) | ||||
| * Supporto integrato ed automatico per le [revisioni degli appunti](https://triliumnext.github.io/Docs/Wiki/note-revisions) | ||||
| * Gli [attributi](https://triliumnext.github.io/Docs/Wiki/attributes) degli appunti possono essere utilizzati per l'organizzazione, per l'interrogazione e per lo scripting avanzato (prorgrammazione). | ||||
| * [Sincronizzazione](https://triliumnext.github.io/Docs/Wiki/synchronization) con un server di sincronizzazione auto-ospitato | ||||
|   * c'è un [servizio di terze parti per ospitare server di sincronizzazione](https://trilium.cc/paid-hosting) | ||||
| * [Condivisione](https://triliumnext.github.io/Docs/Wiki/sharing)  (pubblicazione) di appunti sull'internet pubblico | ||||
| * Robusta [crittografia](https://triliumnext.github.io/Docs/Wiki/protected-notes) configurabile singolarmente per ogni appunto | ||||
| * Disegno di diagrammi con Excalidraw (tipo di appunto "canvas") | ||||
| * [Mappe relazionali](https://triliumnext.github.io/Docs/Wiki/relation-map) e [mappe di collegamenti](https://triliumnext.github.io/Docs/Wiki/link-map) per visualizzare gli appunti e le loro relazioni | ||||
| * [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - vedi [Esempi avanzati](https://triliumnext.github.io/Docs/Wiki/advanced-showcases) | ||||
| * [API REST](https://triliumnext.github.io/Docs/Wiki/etapi) per l'automazione | ||||
| * Si adatta bene sia in termini di usabilità che di prestazioni fino ad oltre 100 000 appunti | ||||
| * Interfaccia utente ottimizzata per il [mobile](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) (smartphone e tablet) | ||||
| * [Tema Notturno](https://triliumnext.github.io/Docs/Wiki/themes) | ||||
| * Supporto per importazione ed esportazione da e per [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) e [Markdown import](https://triliumnext.github.io/Docs/Wiki/markdown) | ||||
| * [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) per il salvataggio facile di contenuti web | ||||
|  | ||||
| ✨ Dai un'occhiata alle seguenti risorse di terze parti per scoprire altre bellezze legate a TriliumNext: | ||||
|  | ||||
| -[awesome-trilium](https://github.com/Nriver/awesome-trilium) per temi, script, plugin e altro di terze parti. | ||||
| - [TriliumRocks!](https://trilium.rocks/) per tutorial, guide e molto altro. | ||||
| ## 🏗 Rilasci | ||||
|  | ||||
|  | ||||
| Trilium è fornito come applicazione desktop (Linux e Windows) o come applicazione web ospitata sul tuo server (Linux). La versione desktop per Mac OS è disponibile, ma [non è supportata](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support). | ||||
|  | ||||
| * Se vuoi usare Trilium sul tuo desktop, scarica il rilascio binario per la tua piattaforma dall'[ultimo rilascio](https://github.com/TriliumNext/Notes/releases/latest), decomprimi l'archivio e avvia l'eseguibile ```trilium```. | ||||
| * Se vuoi installare Trilium su un server, segui [questa pagina](https://triliumnext.github.io/Docs/Wiki/server-installation). | ||||
|   * Per ora solo Chrome e Firefox sono i browser supportati (testati). | ||||
|  | ||||
| TriliumNext sarà fornito anche come Flatpak: | ||||
|  | ||||
| <img width="240" src="https://flathub.org/assets/badges/flathub-badge-en.png"> | ||||
|  | ||||
| ## 📝 Documentazione | ||||
|  | ||||
| [Vedi la wiki per una lista completa delle pagine di documentazione.](https://triliumnext.github.io/Docs/) | ||||
|  | ||||
| Puoi anche leggere ["Patterns of personal knowledge base"](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge) per avere un'ispirazione su come potresti utilizzare Trilium. | ||||
|  | ||||
| ## 💻 Contribuire | ||||
|  | ||||
| Clona localmente ed esegui | ||||
|  | ||||
| ```shell | ||||
| npm install | ||||
| npm run start-server | ||||
| ``` | ||||
|  | ||||
| ## 👏 Riconoscimenti | ||||
|  | ||||
| * [CKEditor 5](https://github.com/ckeditor/ckeditor5) - miglior editor visuale (WYSIWYG) sul mercato, squadra di sviluppo attenta e reattiva | ||||
| * [FancyTree](https://github.com/mar10/fancytree) -  libreria per alberi molto ricca di funzionalità, senza pari. Trilium Notes non sarebbe lo stesso senza di essa. | ||||
| * [CodeMirror](https://github.com/codemirror/CodeMirror) - editor di codice con supporto per un'enorme quantità di linguaggi. | ||||
| * [jsPlumb](https://github.com/jsplumb/jsplumb) - libreria per la  connettività visuale senza pari. Utilizzata per [mappe relazionali](https://triliumnext.github.io/Docs/Wiki/relation-map) e [mappe di collegamenti](https://triliumnext.github.io/Docs/Wiki/link-map). | ||||
|  | ||||
| ## 🤝 Supporto | ||||
|  | ||||
| Puoi sostenere lo sviluppatore originale di Trilium utilizzando gli sponsor di GitHub, [PayPal](https://paypal.me/za4am) o Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). | ||||
| Il supporto all'organizzazione TriliumNext sarà possibile nel prossimo futuro. | ||||
|  | ||||
| ## 🔑 Licenza | ||||
|  | ||||
| Questo programma è software libero: è possibile redistribuirlo e/o modificarlo nei termini della GNU Affero General Public License come pubblicata dalla Free Software Foundation, sia la versione 3 della Licenza, o (a propria scelta) qualsiasi versione successiva. | ||||
							
								
								
									
										73
									
								
								docs/backend_api/media/README.ja.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,73 @@ | ||||
| # TriliumNext Notes | ||||
|  | ||||
| [English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) | ||||
|  | ||||
| Trilium Notes は、大規模な個人知識ベースの構築に焦点を当てた、階層型ノートアプリケーションです。概要は[スクリーンショット](https://triliumnext.github.io/Docs/Wiki/screenshot-tour)をご覧ください: | ||||
|  | ||||
| <a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://raw.githubusercontent.com/wiki/zadam/trilium/images/screenshot.png" alt="Trilium Screenshot" width="1000"></a> | ||||
|  | ||||
| ## 🎁 特徴 | ||||
|  | ||||
| * ノートは、任意の深さのツリーに配置できます。単一のノートをツリー内の複数の場所に配置できます ([cloning](https://triliumnext.github.io/Docs/Wiki/cloning-notes) を参照) | ||||
| * マークダウン[オートフォーマット](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)による、表、画像、[数学](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support)などの豊富な WYSIWYG ノート編集機能 | ||||
| * シンタックスハイライトを含む[ソースコード付きノート](https://triliumnext.github.io/Docs/Wiki/code-notes)の編集をサポート | ||||
| * [ノート間のナビゲーション](https://triliumnext.github.io/Docs/Wiki/note-navigation)、全文検索、[ノートホイスト](https://triliumnext.github.io/Docs/Wiki/note-hoisting)が高速かつ簡単に行えます | ||||
| * シームレスな[ノートのバージョン管理](https://triliumnext.github.io/Docs/Wiki/note-revisions) | ||||
| * ノート[属性](https://triliumnext.github.io/Docs/Wiki/Attributes)は、ノート整理、クエリ、高度な[スクリプト](https://triliumnext.github.io/Docs/Wiki/scripts)に使用できます | ||||
| * 自己ホスト型同期サーバーとの[同期](https://triliumnext.github.io/Docs/Wiki/synchronization) | ||||
|   * [同期サーバーをホストするサードパーティ・サービス](https://trilium.cc/paid-hosting)があります | ||||
| * 公開インターネットへのノートの[共有](https://triliumnext.github.io/Docs/Wiki/sharing)(公開) | ||||
| * ノートごとの粒度を持つ強力な[ノート暗号化](https://triliumnext.github.io/Docs/Wiki/protected-notes) | ||||
| * 組み込みの Excalidraw を使用した図のスケッチ (ノート タイプ"キャンバス") | ||||
| * ノートとその関係を可視化するための[関係図](https://triliumnext.github.io/Docs/Wiki/relation-map)と[リンクマップ](https://triliumnext.github.io/Docs/Wiki/link-map) | ||||
| * [スクリプティング](https://triliumnext.github.io/Docs/Wiki/scripts) - [高度なショーケース](https://triliumnext.github.io/Docs/Wiki/advanced-showcases)を参照 | ||||
| * 自動化のための [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) | ||||
| * ユーザビリティとパフォーマンスの両方で 100 000 ノート以上に拡張可能 | ||||
| * スマートフォンとタブレット向けのタッチ最適化[モバイルフロントエンド](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) | ||||
| * [ナイトテーマ](https://triliumnext.github.io/Docs/Wiki/themes) | ||||
| * [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) と [Markdown のインポートとエクスポート](https://triliumnext.github.io/Docs/Wiki/Markdown) | ||||
| * Web コンテンツを簡単に保存するための [Web クリッパー](https://triliumnext.github.io/Docs/Wiki/web-clipper) | ||||
|  | ||||
| サードパーティのテーマ、スクリプト、プラグインなどは、 [awesome-trilium](https://github.com/Nriver/awesome-trilium) をチェックしてください。 | ||||
|  | ||||
| ## 🏗 ビルド | ||||
|  | ||||
| Trilium は、デスクトップアプリケーション(Linux、Windows)またはサーバー上でホストされるウェブアプリケーション(Linux)として提供されます。 Mac OS のデスクトップビルドも利用可能ですが、 [unsupported](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support) となっています。 | ||||
|  | ||||
| * デスクトップで Trilium を使用したい場合は、 [latest release](https://github.com/TriliumNext/Notes/releases/latest) からお使いのプラットフォームのバイナリリリースをダウンロードし、パッケージを解凍して ``trilium`` の実行ファイルを実行してください。 | ||||
| * サーバーに Trilium をインストールする場合は、[このページ](https://triliumnext.github.io/Docs/Wiki/server-installation)に従ってください。 | ||||
|   * 現在、対応(動作確認)しているブラウザは、最近の Chrome と Firefox のみです。 | ||||
|  | ||||
| Trilium は Flatpak としても提供されます: | ||||
|  | ||||
| [<img width="240" src="https://flathub.org/assets/badges/flathub-badge-en.png">](https://flathub.org/apps/details/com.github.zadam.trilium) | ||||
|  | ||||
| ## 📝 ドキュメント | ||||
|  | ||||
| [ドキュメントページの全リストはwikiをご覧ください。](https://triliumnext.github.io/Docs/) | ||||
|  | ||||
| また、[個人的な知識基盤のパターン](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge)を読むと、 Trilium の使い方のヒントを得ることができます。 | ||||
|  | ||||
| ## 💻 コントリビュート | ||||
|  | ||||
| または、ローカルにクローンして実行 | ||||
|  | ||||
| ```shell | ||||
| npm install | ||||
| npm run start-server | ||||
| ``` | ||||
|  | ||||
| ## 📢 シャウトアウト | ||||
|  | ||||
| * [CKEditor 5](https://github.com/ckeditor/ckeditor5) - 市場で最高の WYSIWYG エディター、非常にインタラクティブで聞き上手なチーム | ||||
| * [FancyTree](https://github.com/mar10/fancytree) - 真の競争相手がいない、非常に機能豊富なツリーライブラリです。 Trilium Notes は、これなしでは成り立たないでしょう。 | ||||
| * [CodeMirror](https://github.com/codemirror/CodeMirror) - 膨大な数の言語をサポートするコードエディタ | ||||
| * [jsPlumb](https://github.com/jsplumb/jsplumb) - 競合のないビジュアルコネクティビティライブラリです。[関係図](https://triliumnext.github.io/Docs/Wiki/relation-map)、[リンク図](https://triliumnext.github.io/Docs/Wiki/link-map)で使用。 | ||||
|  | ||||
| ## 🤝 サポート | ||||
|  | ||||
| GitHub スポンサー、[PayPal](https://paypal.me/za4am)もしくは Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2) にて Trilium をサポートすることができます。 | ||||
|  | ||||
| ## 🔑 ライセンス | ||||
|  | ||||
| このプログラムはフリーソフトウェアです:フリーソフトウェア財団が発行した GNU Affero General Public License のバージョン3、またはそれ以降のバージョンのいずれかに従って、再配布および/または改変することができます。 | ||||
							
								
								
									
										126
									
								
								docs/backend_api/media/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,126 @@ | ||||
| # TriliumNext Notes | ||||
|  | ||||
|   | ||||
|  | ||||
| [English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) | ||||
|  | ||||
| TriliumNext Notes is an open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases. | ||||
|  | ||||
| See [screenshots](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) for quick overview: | ||||
|  | ||||
| <a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a> | ||||
|  | ||||
| ## ⚠️ Why TriliumNext? | ||||
|  | ||||
| [The original Trilium project is in maintenance mode](https://github.com/zadam/trilium/issues/4620) | ||||
|  | ||||
| ### Migrating from Trilium? | ||||
|  | ||||
| There are no special migration steps to migrate from a zadam/Trilium instance to a TriliumNext/Notes instance. Just upgrade your Trilium instance to the latest version and [install TriliumNext/Notes as usual](#-installation) | ||||
|  | ||||
| Versions up to and including [v0.90.4](https://github.com/TriliumNext/Notes/releases/tag/v0.90.4) are compatible with the latest zadam/trilium version of [v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later versions of TriliumNext have their sync versions incremented. | ||||
|  | ||||
| ## 💬 Discuss with us | ||||
|  | ||||
| Feel free to join our official conversations. We would love to hear what features, suggestions, or issues you may have! | ||||
|  | ||||
| - [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous discussions) | ||||
|   - The `General` Matrix room is also bridged to [XMPP](xmpp:discuss@trilium.thisgreat.party?join) | ||||
| - [Github Discussions](https://github.com/TriliumNext/Notes/discussions) (For Asynchronous discussions) | ||||
| - [Wiki](https://triliumnext.github.io/Docs/) (For common how-to questions and user guides) | ||||
|  | ||||
| ## 🎁 Features | ||||
|  | ||||
| * Notes can be arranged into arbitrarily deep tree. Single note can be placed into multiple places in the tree (see [cloning](https://triliumnext.github.io/Docs/Wiki/cloning-notes)) | ||||
| * Rich WYSIWYG note editing including e.g. tables, images and [math](https://triliumnext.github.io/Docs/Wiki/text-notes) with markdown [autoformat](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat) | ||||
| * Support for editing [notes with source code](https://triliumnext.github.io/Docs/Wiki/code-notes), including syntax highlighting | ||||
| * Fast and easy [navigation between notes](https://triliumnext.github.io/Docs/Wiki/note-navigation), full text search and [note hoisting](https://triliumnext.github.io/Docs/Wiki/note-hoisting) | ||||
| * Seamless [note versioning](https://triliumnext.github.io/Docs/Wiki/note-revisions) | ||||
| * Note [attributes](https://triliumnext.github.io/Docs/Wiki/attributes) can be used for note organization, querying and advanced [scripting](https://triliumnext.github.io/Docs/Wiki/scripts) | ||||
| * [Synchronization](https://triliumnext.github.io/Docs/Wiki/synchronization) with self-hosted sync server | ||||
|   * there's a [3rd party service for hosting synchronisation server](https://trilium.cc/paid-hosting) | ||||
| * [Sharing](https://triliumnext.github.io/Docs/Wiki/sharing) (publishing) notes to public internet | ||||
| * Strong [note encryption](https://triliumnext.github.io/Docs/Wiki/protected-notes) with per-note granularity | ||||
| * Sketching diagrams with built-in Excalidraw (note type "canvas") | ||||
| * [Relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map) and [link maps](https://triliumnext.github.io/Docs/Wiki/link-map) for visualizing notes and their relations | ||||
| * [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - see [Advanced showcases](https://triliumnext.github.io/Docs/Wiki/advanced-showcases) | ||||
| * [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) for automation | ||||
| * Scales well in both usability and performance upwards of 100 000 notes | ||||
| * Touch optimized [mobile frontend](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) for smartphones and tablets | ||||
| * [Night theme](https://triliumnext.github.io/Docs/Wiki/themes) | ||||
| * [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) and [Markdown import & export](https://triliumnext.github.io/Docs/Wiki/markdown) | ||||
| * [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) for easy saving of web content | ||||
|  | ||||
| ✨ Check out the following third-party resources/communities for more TriliumNext related goodies: | ||||
|  | ||||
| - [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party themes, scripts, plugins and more. | ||||
| - [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. | ||||
|  | ||||
| ## 🏗 Installation | ||||
|  | ||||
| ### Desktop | ||||
|  | ||||
| To use TriliumNext on your desktop machine (Linux, MacOS, and Windows) you have a few options: | ||||
|  | ||||
| * Download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Notes/releases/latest), unzip the package and run the ```trilium``` executable. | ||||
| * Access TriliumNext via the web interface of a server installation (see below) | ||||
|     * Currently only the latest versions of Chrome & Firefox are supported (and tested). | ||||
| * (Coming Soon) TriliumNext will also be provided as a Flatpak | ||||
|  | ||||
| #### MacOS | ||||
| Currently when running TriliumNext/Notes on MacOS, you may get the following error: | ||||
| > Apple could not verify "TriliumNext Notes" is free of malware and may harm your Mac or compromise your privacy. | ||||
|  | ||||
| You will need to run the command on your shell to resolve the error (documented [here](https://github.com/TriliumNext/Notes/issues/329#issuecomment-2287164137)): | ||||
|  | ||||
| ```bash | ||||
| xattr -c "/path/to/Trilium Next.app" | ||||
| ``` | ||||
|  | ||||
| ### Mobile | ||||
|  | ||||
| To use TriliumNext on a mobile device: | ||||
|  | ||||
| * Use a mobile web browser to access the mobile interface of a server installation (see below) | ||||
| * Use of a mobile app is not yet supported ([see here](https://github.com/TriliumNext/Notes/issues/72)) to track mobile improvements. | ||||
|  | ||||
| ### Server | ||||
|  | ||||
| To install TriliumNext on your own server (including via Docker from [Dockerhub](https://hub.docker.com/r/triliumnext/notes)) follow [the server installation docs](https://triliumnext.github.io/Docs/Wiki/server-installation). | ||||
|  | ||||
| ## 📝 Documentation | ||||
|  | ||||
| [See wiki for complete list of documentation pages.](https://triliumnext.github.io/Docs) | ||||
|  | ||||
| You can also read [Patterns of personal knowledge base](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge) to get some inspiration on how you might use TriliumNext. | ||||
|  | ||||
| ## 💻 Contribute | ||||
|  | ||||
| ### Code | ||||
|  | ||||
| ```shell | ||||
| git clone https://github.com/TriliumNext/Notes.git | ||||
| cd Notes | ||||
| npm install | ||||
| npm run start-server | ||||
| ``` | ||||
|  | ||||
| ### Documentation | ||||
|  | ||||
| Head on over to our [Docs repo](https://github.com/TriliumNext/Docs) | ||||
|  | ||||
| ## 👏 Shoutouts | ||||
|  | ||||
| * [CKEditor 5](https://github.com/ckeditor/ckeditor5) - best WYSIWYG editor on the market, very interactive and listening team | ||||
| * [FancyTree](https://github.com/mar10/fancytree) - very feature rich tree library without real competition. TriliumNext Notes would not be the same without it. | ||||
| * [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with support for huge amount of languages | ||||
| * [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library without competition. Used in [relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map.html) and [link maps](https://triliumnext.github.io/Docs/Wiki/note-map.html#link-map) | ||||
|  | ||||
| ## 🤝 Support | ||||
|  | ||||
| You can support the original Trilium developer using GitHub Sponsors, [PayPal](https://paypal.me/za4am) or Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). | ||||
| Support for the TriliumNext organization will be possible in the near future. | ||||
|  | ||||
| ## 🔑 License | ||||
|  | ||||
| This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. | ||||
							
								
								
									
										59
									
								
								docs/backend_api/media/README.ru.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,59 @@ | ||||
| # TriliumNext Notes | ||||
|  | ||||
| [English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) | ||||
|  | ||||
| Trilium Notes – это приложение для заметок с иерархической структурой, ориентированное на создание больших персональных баз знаний. Для быстрого ознакомления посмотрите [скриншот-тур](https://triliumnext.github.io/Docs/Wiki/screenshot-tour): | ||||
|  | ||||
| <a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a> | ||||
|  | ||||
| ## 🎁 Возможности | ||||
|  | ||||
| * Заметки можно расположить в виде дерева произвольной глубины. Отдельную заметку можно разместить в нескольких местах дерева (см. [клонирование](https://triliumnext.github.io/Docs/Wiki/cloning-notes)) | ||||
| * Продвинутый визуальный редактор (WYSIWYG) позволяет работать с таблицами, изображениями, [формулами](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support) и разметкой markdown, имеет [автоформатирование](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat) | ||||
| * Редактирование [заметок с исходным кодом](https://triliumnext.github.io/Docs/Wiki/code-notes), включая подсветку синтаксиса | ||||
| * Быстрая и простая [навигация между заметками](https://triliumnext.github.io/Docs/Wiki/note-navigation), полнотекстовый поиск и [выделение заметок](https://triliumnext.github.io/Docs/Wiki/note-hoisting) в отдельный блок | ||||
| * Бесшовное [версионирование заметки](https://triliumnext.github.io/Docs/Wiki/note-revisions) | ||||
| * Специальные [атрибуты](https://triliumnext.github.io/Docs/Wiki/attributes) позволяют гибко организовать структуру, используются для поиска и продвинутого [скриптинга](https://triliumnext.github.io/Docs/Wiki/scripts) | ||||
| * [Синхронизация](https://triliumnext.github.io/Docs/Wiki/synchronization) заметок со своим сервером | ||||
| * Надёжное [шифрование](https://triliumnext.github.io/Docs/Wiki/protected-notes) с детализацией по каждой заметке | ||||
| * [Карты связей](https://triliumnext.github.io/Docs/Wiki/relation-map) и [карты ссылок](https://triliumnext.github.io/Docs/Wiki/link-map) для визуализации их взяимосвязей | ||||
| * [Скрипты](https://triliumnext.github.io/Docs/Wiki/scripts) - см. [продвинутые примеры](https://triliumnext.github.io/Docs/Wiki/advanced-showcases) | ||||
| * Хорошо масштабируется, как по удобству использования, так и по производительности до 100000 заметок | ||||
| * Оптимизированный [мобильный фронтенд](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) смартфонов и планшетов | ||||
| * [Темная тема](https://triliumnext.github.io/Docs/Wiki/themes) | ||||
| * Импорт и экпорт [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) и данных в [markdown](https://triliumnext.github.io/Docs/Wiki/markdown) формате | ||||
| * [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) для удобного сохранения веб-контента | ||||
|  | ||||
| ## 🏗 Сборки | ||||
|  | ||||
| Trilium предоставляется в виде десктопного приложения (Linux и Windows) или веб-приложения, размещенного на вашем сервере (Linux). Доступна сборка Mac OS, но она [не поддерживается](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support). | ||||
|  | ||||
| * Если вы хотите использовать Trilium на десктопе, скачайте архив для своей платформы со страницы [релизов](https://github.com/TriliumNext/Notes/releases/latest), распакуйте и запустите исполняемый файл ```trilium```. | ||||
| * Если вы хотите установить Trilium на сервере, следуйте этой [инструкции](https://triliumnext.github.io/Docs/Wiki/server-installation). | ||||
|   * В данный момент поддерживаются (протестированы) последние версии браузеров Chrome и Firefox. | ||||
|  | ||||
| ## 📝 Документация | ||||
|  | ||||
| [Полный список страниц документации доступен в Wiki.](https://triliumnext.github.io/Docs/) | ||||
|  | ||||
| Вы также можете ознакомиться с [шаблонами персональных баз знаний](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge), чтобы получить представление о том, как можно использовать Trilium. | ||||
|  | ||||
| ## 💻 Участвуйте в разработке | ||||
|  | ||||
| Или склонируйте на своё устройство и запустите | ||||
|  | ||||
| ```shell | ||||
| npm install | ||||
| npm run start-server | ||||
| ``` | ||||
|  | ||||
| ## 👏 Благодарности | ||||
|  | ||||
| * [CKEditor 5](https://github.com/ckeditor/ckeditor5) - лучший WYSIWYG редактор, очень активная и внимательная команда. | ||||
| * [FancyTree](https://github.com/mar10/fancytree) - многофункциональная библиотека для создания древовидных структур. Вне конкуренции. Без него Trilium Notes не были бы таким. | ||||
| * [CodeMirror](https://github.com/codemirror/CodeMirror) - редактор кода с поддержкой огромного количество языков. | ||||
| * [jsPlumb](https://github.com/jsplumb/jsplumb) - библиотека для визуализации связей. Вне конкуренции. Используется в [картах связей](https://triliumnext.github.io/Docs/Wiki/relation-map) и [картах ссылок](https://triliumnext.github.io/Docs/Wiki/link-map). | ||||
|  | ||||
| ## 🔑 Лицензия | ||||
|  | ||||
| Эта программа является бесплатным программным обеспечением: вы можете распространять и/или изменять ее в соответствии с условиями GNU Affero General Public License, опубликованной Free Software Foundation, либо версии 3 Лицензии, либо (по вашему выбору) любой более поздней версии. | ||||
							
								
								
									
										1
									
								
								docs/backend_api/modules.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1
									
								
								docs/backend_api/modules/becca_entities_battachment.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1
									
								
								docs/backend_api/modules/becca_entities_battribute.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1
									
								
								docs/backend_api/modules/becca_entities_bblob.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1
									
								
								docs/backend_api/modules/becca_entities_bbranch.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1
									
								
								docs/backend_api/modules/becca_entities_bnote.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1
									
								
								docs/backend_api/modules/becca_entities_boption.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1
									
								
								docs/backend_api/modules/becca_entities_brevision.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1
									
								
								docs/backend_api/modules/becca_entities_rows.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1
									
								
								docs/backend_api/modules/services_sql.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -1,25 +0,0 @@ | ||||
| /*global document */ | ||||
| (() => { | ||||
|     const source = document.getElementsByClassName('prettyprint source linenums'); | ||||
|     let i = 0; | ||||
|     let lineNumber = 0; | ||||
|     let lineId; | ||||
|     let lines; | ||||
|     let totalLines; | ||||
|     let anchorHash; | ||||
|  | ||||
|     if (source && source[0]) { | ||||
|         anchorHash = document.location.hash.substring(1); | ||||
|         lines = source[0].getElementsByTagName('li'); | ||||
|         totalLines = lines.length; | ||||
|  | ||||
|         for (; i < totalLines; i++) { | ||||
|             lineNumber++; | ||||
|             lineId = `line${lineNumber}`; | ||||
|             lines[i].id = lineId; | ||||
|             if (lineId === anchorHash) { | ||||
|                 lines[i].className += ' selected'; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| })(); | ||||
| @@ -1,202 +0,0 @@ | ||||
|  | ||||
|                                  Apache License | ||||
|                            Version 2.0, January 2004 | ||||
|                         http://www.apache.org/licenses/ | ||||
|  | ||||
|    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||||
|  | ||||
|    1. Definitions. | ||||
|  | ||||
|       "License" shall mean the terms and conditions for use, reproduction, | ||||
|       and distribution as defined by Sections 1 through 9 of this document. | ||||
|  | ||||
|       "Licensor" shall mean the copyright owner or entity authorized by | ||||
|       the copyright owner that is granting the License. | ||||
|  | ||||
|       "Legal Entity" shall mean the union of the acting entity and all | ||||
|       other entities that control, are controlled by, or are under common | ||||
|       control with that entity. For the purposes of this definition, | ||||
|       "control" means (i) the power, direct or indirect, to cause the | ||||
|       direction or management of such entity, whether by contract or | ||||
|       otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||||
|       outstanding shares, or (iii) beneficial ownership of such entity. | ||||
|  | ||||
|       "You" (or "Your") shall mean an individual or Legal Entity | ||||
|       exercising permissions granted by this License. | ||||
|  | ||||
|       "Source" form shall mean the preferred form for making modifications, | ||||
|       including but not limited to software source code, documentation | ||||
|       source, and configuration files. | ||||
|  | ||||
|       "Object" form shall mean any form resulting from mechanical | ||||
|       transformation or translation of a Source form, including but | ||||
|       not limited to compiled object code, generated documentation, | ||||
|       and conversions to other media types. | ||||
|  | ||||
|       "Work" shall mean the work of authorship, whether in Source or | ||||
|       Object form, made available under the License, as indicated by a | ||||
|       copyright notice that is included in or attached to the work | ||||
|       (an example is provided in the Appendix below). | ||||
|  | ||||
|       "Derivative Works" shall mean any work, whether in Source or Object | ||||
|       form, that is based on (or derived from) the Work and for which the | ||||
|       editorial revisions, annotations, elaborations, or other modifications | ||||
|       represent, as a whole, an original work of authorship. For the purposes | ||||
|       of this License, Derivative Works shall not include works that remain | ||||
|       separable from, or merely link (or bind by name) to the interfaces of, | ||||
|       the Work and Derivative Works thereof. | ||||
|  | ||||
|       "Contribution" shall mean any work of authorship, including | ||||
|       the original version of the Work and any modifications or additions | ||||
|       to that Work or Derivative Works thereof, that is intentionally | ||||
|       submitted to Licensor for inclusion in the Work by the copyright owner | ||||
|       or by an individual or Legal Entity authorized to submit on behalf of | ||||
|       the copyright owner. For the purposes of this definition, "submitted" | ||||
|       means any form of electronic, verbal, or written communication sent | ||||
|       to the Licensor or its representatives, including but not limited to | ||||
|       communication on electronic mailing lists, source code control systems, | ||||
|       and issue tracking systems that are managed by, or on behalf of, the | ||||
|       Licensor for the purpose of discussing and improving the Work, but | ||||
|       excluding communication that is conspicuously marked or otherwise | ||||
|       designated in writing by the copyright owner as "Not a Contribution." | ||||
|  | ||||
|       "Contributor" shall mean Licensor and any individual or Legal Entity | ||||
|       on behalf of whom a Contribution has been received by Licensor and | ||||
|       subsequently incorporated within the Work. | ||||
|  | ||||
|    2. Grant of Copyright License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       copyright license to reproduce, prepare Derivative Works of, | ||||
|       publicly display, publicly perform, sublicense, and distribute the | ||||
|       Work and such Derivative Works in Source or Object form. | ||||
|  | ||||
|    3. Grant of Patent License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       (except as stated in this section) patent license to make, have made, | ||||
|       use, offer to sell, sell, import, and otherwise transfer the Work, | ||||
|       where such license applies only to those patent claims licensable | ||||
|       by such Contributor that are necessarily infringed by their | ||||
|       Contribution(s) alone or by combination of their Contribution(s) | ||||
|       with the Work to which such Contribution(s) was submitted. If You | ||||
|       institute patent litigation against any entity (including a | ||||
|       cross-claim or counterclaim in a lawsuit) alleging that the Work | ||||
|       or a Contribution incorporated within the Work constitutes direct | ||||
|       or contributory patent infringement, then any patent licenses | ||||
|       granted to You under this License for that Work shall terminate | ||||
|       as of the date such litigation is filed. | ||||
|  | ||||
|    4. Redistribution. You may reproduce and distribute copies of the | ||||
|       Work or Derivative Works thereof in any medium, with or without | ||||
|       modifications, and in Source or Object form, provided that You | ||||
|       meet the following conditions: | ||||
|  | ||||
|       (a) You must give any other recipients of the Work or | ||||
|           Derivative Works a copy of this License; and | ||||
|  | ||||
|       (b) You must cause any modified files to carry prominent notices | ||||
|           stating that You changed the files; and | ||||
|  | ||||
|       (c) You must retain, in the Source form of any Derivative Works | ||||
|           that You distribute, all copyright, patent, trademark, and | ||||
|           attribution notices from the Source form of the Work, | ||||
|           excluding those notices that do not pertain to any part of | ||||
|           the Derivative Works; and | ||||
|  | ||||
|       (d) If the Work includes a "NOTICE" text file as part of its | ||||
|           distribution, then any Derivative Works that You distribute must | ||||
|           include a readable copy of the attribution notices contained | ||||
|           within such NOTICE file, excluding those notices that do not | ||||
|           pertain to any part of the Derivative Works, in at least one | ||||
|           of the following places: within a NOTICE text file distributed | ||||
|           as part of the Derivative Works; within the Source form or | ||||
|           documentation, if provided along with the Derivative Works; or, | ||||
|           within a display generated by the Derivative Works, if and | ||||
|           wherever such third-party notices normally appear. The contents | ||||
|           of the NOTICE file are for informational purposes only and | ||||
|           do not modify the License. You may add Your own attribution | ||||
|           notices within Derivative Works that You distribute, alongside | ||||
|           or as an addendum to the NOTICE text from the Work, provided | ||||
|           that such additional attribution notices cannot be construed | ||||
|           as modifying the License. | ||||
|  | ||||
|       You may add Your own copyright statement to Your modifications and | ||||
|       may provide additional or different license terms and conditions | ||||
|       for use, reproduction, or distribution of Your modifications, or | ||||
|       for any such Derivative Works as a whole, provided Your use, | ||||
|       reproduction, and distribution of the Work otherwise complies with | ||||
|       the conditions stated in this License. | ||||
|  | ||||
|    5. Submission of Contributions. Unless You explicitly state otherwise, | ||||
|       any Contribution intentionally submitted for inclusion in the Work | ||||
|       by You to the Licensor shall be under the terms and conditions of | ||||
|       this License, without any additional terms or conditions. | ||||
|       Notwithstanding the above, nothing herein shall supersede or modify | ||||
|       the terms of any separate license agreement you may have executed | ||||
|       with Licensor regarding such Contributions. | ||||
|  | ||||
|    6. Trademarks. This License does not grant permission to use the trade | ||||
|       names, trademarks, service marks, or product names of the Licensor, | ||||
|       except as required for reasonable and customary use in describing the | ||||
|       origin of the Work and reproducing the content of the NOTICE file. | ||||
|  | ||||
|    7. Disclaimer of Warranty. Unless required by applicable law or | ||||
|       agreed to in writing, Licensor provides the Work (and each | ||||
|       Contributor provides its Contributions) on an "AS IS" BASIS, | ||||
|       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||||
|       implied, including, without limitation, any warranties or conditions | ||||
|       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||||
|       PARTICULAR PURPOSE. You are solely responsible for determining the | ||||
|       appropriateness of using or redistributing the Work and assume any | ||||
|       risks associated with Your exercise of permissions under this License. | ||||
|  | ||||
|    8. Limitation of Liability. In no event and under no legal theory, | ||||
|       whether in tort (including negligence), contract, or otherwise, | ||||
|       unless required by applicable law (such as deliberate and grossly | ||||
|       negligent acts) or agreed to in writing, shall any Contributor be | ||||
|       liable to You for damages, including any direct, indirect, special, | ||||
|       incidental, or consequential damages of any character arising as a | ||||
|       result of this License or out of the use or inability to use the | ||||
|       Work (including but not limited to damages for loss of goodwill, | ||||
|       work stoppage, computer failure or malfunction, or any and all | ||||
|       other commercial damages or losses), even if such Contributor | ||||
|       has been advised of the possibility of such damages. | ||||
|  | ||||
|    9. Accepting Warranty or Additional Liability. While redistributing | ||||
|       the Work or Derivative Works thereof, You may choose to offer, | ||||
|       and charge a fee for, acceptance of support, warranty, indemnity, | ||||
|       or other liability obligations and/or rights consistent with this | ||||
|       License. However, in accepting such obligations, You may act only | ||||
|       on Your own behalf and on Your sole responsibility, not on behalf | ||||
|       of any other Contributor, and only if You agree to indemnify, | ||||
|       defend, and hold each Contributor harmless for any liability | ||||
|       incurred by, or claims asserted against, such Contributor by reason | ||||
|       of your accepting any such warranty or additional liability. | ||||
|  | ||||
|    END OF TERMS AND CONDITIONS | ||||
|  | ||||
|    APPENDIX: How to apply the Apache License to your work. | ||||
|  | ||||
|       To apply the Apache License to your work, attach the following | ||||
|       boilerplate notice, with the fields enclosed by brackets "[]" | ||||
|       replaced with your own identifying information. (Don't include | ||||
|       the brackets!)  The text should be enclosed in the appropriate | ||||
|       comment syntax for the file format. We also recommend that a | ||||
|       file or class name and description of purpose be included on the | ||||
|       same "printed page" as the copyright notice for easier | ||||
|       identification within third-party archives. | ||||
|  | ||||
|    Copyright [yyyy] [name of copyright owner] | ||||
|  | ||||
|    Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|    you may not use this file except in compliance with the License. | ||||
|    You may obtain a copy of the License at | ||||
|  | ||||
|        http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
|    Unless required by applicable law or agreed to in writing, software | ||||
|    distributed under the License is distributed on an "AS IS" BASIS, | ||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|    See the License for the specific language governing permissions and | ||||
|    limitations under the License. | ||||
| @@ -1,2 +0,0 @@ | ||||
| PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", | ||||
| /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); | ||||
| @@ -1,28 +0,0 @@ | ||||
| var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; | ||||
| (function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= | ||||
| [],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c< | ||||
| f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&& | ||||
| (j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r= | ||||
| {b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length, | ||||
| t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b=== | ||||
| "string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), | ||||
| l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, | ||||
| q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, | ||||
| q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, | ||||
| "");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), | ||||
| a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} | ||||
| for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value", | ||||
| m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m= | ||||
| a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue= | ||||
| j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], | ||||
| "catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], | ||||
| H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], | ||||
| J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ | ||||
| I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), | ||||
| ["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", | ||||
| /^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), | ||||
| ["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", | ||||
| hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b= | ||||
| !k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m, | ||||
| 250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit", | ||||
| PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})(); | ||||
| @@ -1,735 +0,0 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <title>JSDoc: Source: services/backend_script_api.js</title> | ||||
|  | ||||
|     <script src="scripts/prettify/prettify.js"> </script> | ||||
|     <script src="scripts/prettify/lang-css.js"> </script> | ||||
|     <!--[if lt IE 9]> | ||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> | ||||
|     <![endif]--> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|  | ||||
| <div id="main"> | ||||
|  | ||||
|     <h1 class="page-title">Source: services/backend_script_api.js</h1> | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
|      | ||||
|     <section> | ||||
|         <article> | ||||
|             <pre class="prettyprint source linenums"><code>const log = require('./log'); | ||||
| const noteService = require('./notes'); | ||||
| const sql = require('./sql'); | ||||
| const utils = require('./utils'); | ||||
| const attributeService = require('./attributes'); | ||||
| const dateNoteService = require('./date_notes'); | ||||
| const treeService = require('./tree'); | ||||
| const config = require('./config'); | ||||
| const axios = require('axios'); | ||||
| const dayjs = require('dayjs'); | ||||
| const xml2js = require('xml2js'); | ||||
| const cloningService = require('./cloning'); | ||||
| const appInfo = require('./app_info'); | ||||
| const searchService = require('./search/services/search'); | ||||
| const SearchContext = require("./search/search_context"); | ||||
| const becca = require("../becca/becca"); | ||||
| const ws = require("./ws"); | ||||
| const SpacedUpdate = require("./spaced_update"); | ||||
| const specialNotesService = require("./special_notes"); | ||||
| const branchService = require("./branches"); | ||||
| const exportService = require("./export/zip"); | ||||
| const syncMutex = require("./sync_mutex"); | ||||
| const backupService = require("./backup"); | ||||
| const optionsService = require("./options"); | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * A whole number | ||||
|  * @typedef {number} int | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * An instance of the frontend api available globally. | ||||
|  * @global | ||||
|  * @var {BackendScriptApi} api | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * <p>This is the main backend API interface for scripts. All the properties and methods are published in the "api" object | ||||
|  * available in the JS backend notes. You can use e.g. <code>api.log(api.startNote.title);</code></p> | ||||
|  * | ||||
|  * @constructor | ||||
|  */ | ||||
| function BackendScriptApi(currentNote, apiParams) { | ||||
|     /** | ||||
|      * Note where the script started executing | ||||
|      * @type {BNote} | ||||
|      */ | ||||
|     this.startNote = apiParams.startNote; | ||||
|     /** | ||||
|      * Note where the script is currently executing. Don't mix this up with the concept of active note | ||||
|      * @type {BNote} | ||||
|      */ | ||||
|     this.currentNote = currentNote; | ||||
|     /** | ||||
|      * Entity whose event triggered this execution | ||||
|      * @type {AbstractBeccaEntity} | ||||
|      */ | ||||
|     this.originEntity = apiParams.originEntity; | ||||
|  | ||||
|     for (const key in apiParams) { | ||||
|         this[key] = apiParams[key]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Axios library for HTTP requests. See {@link https://axios-http.com} for documentation | ||||
|      * @type {axios} | ||||
|      * @deprecated use native (browser compatible) fetch() instead | ||||
|      */ | ||||
|     this.axios = axios; | ||||
|     /** | ||||
|      * day.js library for date manipulation. See {@link https://day.js.org} for documentation | ||||
|      * @type {dayjs} | ||||
|      */ | ||||
|     this.dayjs = dayjs; | ||||
|     /** | ||||
|      * xml2js library for XML parsing. See {@link https://github.com/Leonidas-from-XIV/node-xml2js} for documentation | ||||
|      * @type {xml2js} | ||||
|      */ | ||||
|     this.xml2js = xml2js; | ||||
|  | ||||
|     /** | ||||
|      * Instance name identifies particular Trilium instance. It can be useful for scripts | ||||
|      * if some action needs to happen on only one specific instance. | ||||
|      * | ||||
|      * @returns {string|null} | ||||
|      */ | ||||
|     this.getInstanceName = () => config.General ? config.General.instanceName : null; | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @param {string} noteId | ||||
|      * @returns {BNote|null} | ||||
|      */ | ||||
|     this.getNote = noteId => becca.getNote(noteId); | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @param {string} branchId | ||||
|      * @returns {BBranch|null} | ||||
|      */ | ||||
|     this.getBranch = branchId => becca.getBranch(branchId); | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @param {string} attributeId | ||||
|      * @returns {BAttribute|null} | ||||
|      */ | ||||
|     this.getAttribute = attributeId => becca.getAttribute(attributeId); | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @param {string} attachmentId | ||||
|      * @returns {BAttachment|null} | ||||
|      */ | ||||
|     this.getAttachment = attachmentId => becca.getAttachment(attachmentId); | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @param {string} revisionId | ||||
|      * @returns {BRevision|null} | ||||
|      */ | ||||
|     this.getRevision = revisionId => becca.getRevision(revisionId); | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @param {string} etapiTokenId | ||||
|      * @returns {BEtapiToken|null} | ||||
|      */ | ||||
|     this.getEtapiToken = etapiTokenId => becca.getEtapiToken(etapiTokenId); | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @returns {BEtapiToken[]} | ||||
|      */ | ||||
|     this.getEtapiTokens = () => becca.getEtapiTokens(); | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @param {string} optionName | ||||
|      * @returns {BOption|null} | ||||
|      */ | ||||
|     this.getOption = optionName => becca.getOption(optionName); | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @returns {BOption[]} | ||||
|      */ | ||||
|     this.getOptions = () => optionsService.getOptions(); | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @param {string} attributeId | ||||
|      * @returns {BAttribute|null} | ||||
|      */ | ||||
|     this.getAttribute = attributeId => becca.getAttribute(attributeId); | ||||
|  | ||||
|     /** | ||||
|      * This is a powerful search method - you can search by attributes and their values, e.g.: | ||||
|      * "#dateModified =* MONTH AND #log". See {@link https://github.com/zadam/trilium/wiki/Search} for full documentation for all options | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} query | ||||
|      * @param {Object} [searchParams] | ||||
|      * @returns {BNote[]} | ||||
|      */ | ||||
|     this.searchForNotes = (query, searchParams = {}) => { | ||||
|         if (searchParams.includeArchivedNotes === undefined) { | ||||
|             searchParams.includeArchivedNotes = true; | ||||
|         } | ||||
|  | ||||
|         if (searchParams.ignoreHoistedNote === undefined) { | ||||
|             searchParams.ignoreHoistedNote = true; | ||||
|         } | ||||
|  | ||||
|         const noteIds = searchService.findResultsWithQuery(query, new SearchContext(searchParams)) | ||||
|             .map(sr => sr.noteId); | ||||
|  | ||||
|         return becca.getNotes(noteIds); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * This is a powerful search method - you can search by attributes and their values, e.g.: | ||||
|      * "#dateModified =* MONTH AND #log". See {@link https://github.com/zadam/trilium/wiki/Search} for full documentation for all options | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} query | ||||
|      * @param {Object} [searchParams] | ||||
|      * @returns {BNote|null} | ||||
|      */ | ||||
|     this.searchForNote = (query, searchParams = {}) => { | ||||
|         const notes = this.searchForNotes(query, searchParams); | ||||
|  | ||||
|         return notes.length > 0 ? notes[0] : null; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Retrieves notes with given label name & value | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} name - attribute name | ||||
|      * @param {string} [value] - attribute value | ||||
|      * @returns {BNote[]} | ||||
|      */ | ||||
|     this.getNotesWithLabel = attributeService.getNotesWithLabel; | ||||
|  | ||||
|     /** | ||||
|      * Retrieves first note with given label name & value | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} name - attribute name | ||||
|      * @param {string} [value] - attribute value | ||||
|      * @returns {BNote|null} | ||||
|      */ | ||||
|     this.getNoteWithLabel = attributeService.getNoteWithLabel; | ||||
|  | ||||
|     /** | ||||
|      * If there's no branch between note and parent note, create one. Otherwise, do nothing. Returns the new or existing branch. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} noteId | ||||
|      * @param {string} parentNoteId | ||||
|      * @param {string} prefix - if branch is created between note and parent note, set this prefix | ||||
|      * @returns {{branch: BBranch|null}} | ||||
|      */ | ||||
|     this.ensureNoteIsPresentInParent = cloningService.ensureNoteIsPresentInParent; | ||||
|  | ||||
|     /** | ||||
|      * If there's a branch between note and parent note, remove it. Otherwise, do nothing. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} noteId | ||||
|      * @param {string} parentNoteId | ||||
|      * @returns {void} | ||||
|      */ | ||||
|     this.ensureNoteIsAbsentFromParent = cloningService.ensureNoteIsAbsentFromParent; | ||||
|  | ||||
|     /** | ||||
|      * Based on the value, either create or remove branch between note and parent note. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {boolean} present - true if we want the branch to exist, false if we want it gone | ||||
|      * @param {string} noteId | ||||
|      * @param {string} parentNoteId | ||||
|      * @param {string} prefix - if branch is created between note and parent note, set this prefix | ||||
|      * @returns {void} | ||||
|      */ | ||||
|     this.toggleNoteInParent = cloningService.toggleNoteInParent; | ||||
|  | ||||
|     /** | ||||
|      * Create text note. See also createNewNote() for more options. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} parentNoteId | ||||
|      * @param {string} title | ||||
|      * @param {string} content | ||||
|      * @returns {{note: BNote, branch: BBranch}} - object having "note" and "branch" keys representing respective objects | ||||
|      */ | ||||
|     this.createTextNote = (parentNoteId, title, content = '') => noteService.createNewNote({ | ||||
|         parentNoteId, | ||||
|         title, | ||||
|         content, | ||||
|         type: 'text' | ||||
|     }); | ||||
|  | ||||
|     /** | ||||
|      * Create data note - data in this context means object serializable to JSON. Created note will be of type 'code' and | ||||
|      * JSON MIME type. See also createNewNote() for more options. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} parentNoteId | ||||
|      * @param {string} title | ||||
|      * @param {object} content | ||||
|      * @returns {{note: BNote, branch: BBranch}} object having "note" and "branch" keys representing respective objects | ||||
|      */ | ||||
|     this.createDataNote = (parentNoteId, title, content = {}) => noteService.createNewNote({ | ||||
|         parentNoteId, | ||||
|         title, | ||||
|         content: JSON.stringify(content, null, '\t'), | ||||
|         type: 'code', | ||||
|         mime: 'application/json' | ||||
|     }); | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * | ||||
|      * @param {object} params | ||||
|      * @param {string} params.parentNoteId | ||||
|      * @param {string} params.title | ||||
|      * @param {string|Buffer} params.content | ||||
|      * @param {NoteType} params.type - text, code, file, image, search, book, relationMap, canvas | ||||
|      * @param {string} [params.mime] - value is derived from default mimes for type | ||||
|      * @param {boolean} [params.isProtected=false] | ||||
|      * @param {boolean} [params.isExpanded=false] | ||||
|      * @param {string} [params.prefix=''] | ||||
|      * @param {int} [params.notePosition] - default is last existing notePosition in a parent + 10 | ||||
|      * @returns {{note: BNote, branch: BBranch}} object contains newly created entities note and branch | ||||
|      */ | ||||
|     this.createNewNote = noteService.createNewNote; | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @deprecated please use createTextNote() with similar API for simpler use cases or createNewNote() for more complex needs | ||||
|      * | ||||
|      * @param {string} parentNoteId - create new note under this parent | ||||
|      * @param {string} title | ||||
|      * @param {string} [content=""] | ||||
|      * @param {object} [extraOptions={}] | ||||
|      * @param {boolean} [extraOptions.json=false] - should the note be JSON | ||||
|      * @param {boolean} [extraOptions.isProtected=false] - should the note be protected | ||||
|      * @param {string} [extraOptions.type='text'] - note type | ||||
|      * @param {string} [extraOptions.mime='text/html'] - MIME type of the note | ||||
|      * @param {object[]} [extraOptions.attributes=[]] - attributes to be created for this note | ||||
|      * @param {AttributeType} extraOptions.attributes.type - attribute type - label, relation etc. | ||||
|      * @param {string} extraOptions.attributes.name - attribute name | ||||
|      * @param {string} [extraOptions.attributes.value] - attribute value | ||||
|      * @returns {{note: BNote, branch: BBranch}} object contains newly created entities note and branch | ||||
|      */ | ||||
|     this.createNote = (parentNoteId, title, content = "", extraOptions= {}) => { | ||||
|         extraOptions.parentNoteId = parentNoteId; | ||||
|         extraOptions.title = title; | ||||
|  | ||||
|         const parentNote = becca.getNote(parentNoteId); | ||||
|  | ||||
|         // code note type can be inherited, otherwise "text" is the default | ||||
|         extraOptions.type = parentNote.type === 'code' ? 'code' : 'text'; | ||||
|         extraOptions.mime = parentNote.type === 'code' ? parentNote.mime : 'text/html'; | ||||
|  | ||||
|         if (extraOptions.json) { | ||||
|             extraOptions.content = JSON.stringify(content || {}, null, '\t'); | ||||
|             extraOptions.type = 'code'; | ||||
|             extraOptions.mime = 'application/json'; | ||||
|         } | ||||
|         else { | ||||
|             extraOptions.content = content; | ||||
|         } | ||||
|  | ||||
|         return sql.transactional(() => { | ||||
|             const {note, branch} = noteService.createNewNote(extraOptions); | ||||
|  | ||||
|             for (const attr of extraOptions.attributes || []) { | ||||
|                 attributeService.createAttribute({ | ||||
|                     noteId: note.noteId, | ||||
|                     type: attr.type, | ||||
|                     name: attr.name, | ||||
|                     value: attr.value, | ||||
|                     isInheritable: !!attr.isInheritable | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             return {note, branch}; | ||||
|         }); | ||||
|     }; | ||||
|  | ||||
|     this.logMessages = {}; | ||||
|     this.logSpacedUpdates = {}; | ||||
|  | ||||
|     /** | ||||
|      * Log given message to trilium logs and log pane in UI | ||||
|      * | ||||
|      * @method | ||||
|      * @param message | ||||
|      * @returns {void} | ||||
|      */ | ||||
|     this.log = message => { | ||||
|         log.info(message); | ||||
|  | ||||
|         const {noteId} = this.startNote; | ||||
|  | ||||
|         this.logMessages[noteId] = this.logMessages[noteId] || []; | ||||
|         this.logSpacedUpdates[noteId] = this.logSpacedUpdates[noteId] || new SpacedUpdate(() => { | ||||
|             const messages = this.logMessages[noteId]; | ||||
|             this.logMessages[noteId] = []; | ||||
|  | ||||
|             ws.sendMessageToAllClients({ | ||||
|                 type: 'api-log-messages', | ||||
|                 noteId, | ||||
|                 messages | ||||
|             }); | ||||
|         }, 100); | ||||
|  | ||||
|         this.logMessages[noteId].push(message); | ||||
|         this.logSpacedUpdates[noteId].scheduleUpdate(); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Returns root note of the calendar. | ||||
|      * | ||||
|      * @method | ||||
|      * @returns {BNote|null} | ||||
|      */ | ||||
|     this.getRootCalendarNote = dateNoteService.getRootCalendarNote; | ||||
|  | ||||
|     /** | ||||
|      * Returns day note for given date. If such note doesn't exist, it is created. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} date in YYYY-MM-DD format | ||||
|      * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use the default calendar | ||||
|      * @returns {BNote|null} | ||||
|      */ | ||||
|     this.getDayNote = dateNoteService.getDayNote; | ||||
|  | ||||
|     /** | ||||
|      * Returns today's day note. If such note doesn't exist, it is created. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use the default calendar | ||||
|      * @returns {BNote|null} | ||||
|      */ | ||||
|     this.getTodayNote = dateNoteService.getTodayNote; | ||||
|  | ||||
|     /** | ||||
|      * Returns note for the first date of the week of the given date. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} date in YYYY-MM-DD format | ||||
|      * @param {object} [options] | ||||
|      * @param {string} [options.startOfTheWeek=monday] - either "monday" (default) or "sunday" | ||||
|      * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use the default calendar | ||||
|      * @returns {BNote|null} | ||||
|      */ | ||||
|     this.getWeekNote = dateNoteService.getWeekNote; | ||||
|  | ||||
|     /** | ||||
|      * Returns month note for given date. If such a note doesn't exist, it is created. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} date in YYYY-MM format | ||||
|      * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use the default calendar | ||||
|      * @returns {BNote|null} | ||||
|      */ | ||||
|     this.getMonthNote = dateNoteService.getMonthNote; | ||||
|  | ||||
|     /** | ||||
|      * Returns year note for given year. If such a note doesn't exist, it is created. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} year in YYYY format | ||||
|      * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use the default calendar | ||||
|      * @returns {BNote|null} | ||||
|      */ | ||||
|     this.getYearNote = dateNoteService.getYearNote; | ||||
|  | ||||
|     /** | ||||
|      * Sort child notes of a given note. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} parentNoteId - this note's child notes will be sorted | ||||
|      * @param {object} [sortConfig] | ||||
|      * @param {string} [sortConfig.sortBy=title] - 'title', 'dateCreated', 'dateModified' or a label name | ||||
|      *                                See {@link https://github.com/zadam/trilium/wiki/Sorting} for details. | ||||
|      * @param {boolean} [sortConfig.reverse=false] | ||||
|      * @param {boolean} [sortConfig.foldersFirst=false] | ||||
|      * @returns {void} | ||||
|      */ | ||||
|     this.sortNotes = (parentNoteId, sortConfig = {}) => treeService.sortNotes( | ||||
|         parentNoteId, | ||||
|         sortConfig.sortBy || "title", | ||||
|         !!sortConfig.reverse, | ||||
|         !!sortConfig.foldersFirst | ||||
|     ); | ||||
|  | ||||
|     /** | ||||
|      * This method finds note by its noteId and prefix and either sets it to the given parentNoteId | ||||
|      * or removes the branch (if parentNoteId is not given). | ||||
|      * | ||||
|      * This method looks similar to toggleNoteInParent() but differs because we're looking up branch by prefix. | ||||
|      * | ||||
|      * @method | ||||
|      * @deprecated this method is pretty confusing and serves specialized purpose only | ||||
|      * @param {string} noteId | ||||
|      * @param {string} prefix | ||||
|      * @param {string|null} parentNoteId | ||||
|      * @returns {void} | ||||
|      */ | ||||
|     this.setNoteToParent = treeService.setNoteToParent; | ||||
|  | ||||
|     /** | ||||
|      * This functions wraps code which is supposed to be running in transaction. If transaction already | ||||
|      * exists, then we'll use that transaction. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {function} func | ||||
|      * @returns {any} result of func callback | ||||
|      */ | ||||
|     this.transactional = sql.transactional; | ||||
|  | ||||
|     /** | ||||
|      * Return randomly generated string of given length. This random string generation is NOT cryptographically secure. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {int} length of the string | ||||
|      * @returns {string} random string | ||||
|      */ | ||||
|     this.randomString = utils.randomString; | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @param {string} string to escape | ||||
|      * @returns {string} escaped string | ||||
|      */ | ||||
|     this.escapeHtml = utils.escapeHtml; | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @param {string} string to unescape | ||||
|      * @returns {string} unescaped string | ||||
|      */ | ||||
|     this.unescapeHtml = utils.unescapeHtml; | ||||
|  | ||||
|     /** | ||||
|      * sql | ||||
|      * @type {module:sql} | ||||
|      */ | ||||
|     this.sql = sql; | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @returns {{syncVersion, appVersion, buildRevision, dbVersion, dataDirectory, buildDate}|*} - object representing basic info about running Trilium version | ||||
|      */ | ||||
|     this.getAppInfo = () => appInfo; | ||||
|  | ||||
|     /** | ||||
|      * Creates a new launcher to the launchbar. If the launcher (id) already exists, it will be updated. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {object} opts | ||||
|      * @param {string} opts.id - id of the launcher, only alphanumeric at least 6 characters long | ||||
|      * @param {"note" | "script" | "customWidget"} opts.type - one of | ||||
|      *                          * "note" - activating the launcher will navigate to the target note (specified in targetNoteId param) | ||||
|      *                          * "script" -  activating the launcher will execute the script (specified in scriptNoteId param) | ||||
|      *                          * "customWidget" - the launcher will be rendered with a custom widget (specified in widgetNoteId param) | ||||
|      * @param {string} opts.title | ||||
|      * @param {boolean} [opts.isVisible=false] - if true, will be created in the "Visible launchers", otherwise in "Available launchers" | ||||
|      * @param {string} [opts.icon] - name of the boxicon to be used (e.g. "bx-time") | ||||
|      * @param {string} [opts.keyboardShortcut] - will activate the target note/script upon pressing, e.g. "ctrl+e" | ||||
|      * @param {string} [opts.targetNoteId] - for type "note" | ||||
|      * @param {string} [opts.scriptNoteId] - for type "script" | ||||
|      * @param {string} [opts.widgetNoteId] - for type "customWidget" | ||||
|      * @returns {{note: BNote}} | ||||
|      */ | ||||
|     this.createOrUpdateLauncher = opts => { | ||||
|         if (!opts.id) { throw new Error("ID is a mandatory parameter for api.createOrUpdateLauncher(opts)"); } | ||||
|         if (!opts.id.match(/[a-z0-9]{6,1000}/i)) { throw new Error(`ID must be an alphanumeric string at least 6 characters long.`); } | ||||
|         if (!opts.type) { throw new Error("Launcher Type is a mandatory parameter for api.createOrUpdateLauncher(opts)"); } | ||||
|         if (!["note", "script", "customWidget"].includes(opts.type)) { throw new Error(`Given launcher type '${opts.type}'`); } | ||||
|         if (!opts.title?.trim()) { throw new Error("Title is a mandatory parameter for api.createOrUpdateLauncher(opts)"); } | ||||
|         if (opts.type === 'note' && !opts.targetNoteId) { throw new Error("targetNoteId is mandatory for launchers of type 'note'"); } | ||||
|         if (opts.type === 'script' && !opts.scriptNoteId) { throw new Error("scriptNoteId is mandatory for launchers of type 'script'"); } | ||||
|         if (opts.type === 'customWidget' && !opts.widgetNoteId) { throw new Error("widgetNoteId is mandatory for launchers of type 'customWidget'"); } | ||||
|  | ||||
|         const parentNoteId = opts.isVisible ? '_lbVisibleLaunchers' : '_lbAvailableLaunchers'; | ||||
|         const noteId = 'al_' + opts.id; | ||||
|  | ||||
|         const launcherNote = | ||||
|             becca.getNote(noteId) || | ||||
|             specialNotesService.createLauncher({ | ||||
|                 noteId: noteId, | ||||
|                 parentNoteId: parentNoteId, | ||||
|                 launcherType: opts.type, | ||||
|             }).note; | ||||
|  | ||||
|         if (launcherNote.title !== opts.title) { | ||||
|             launcherNote.title = opts.title; | ||||
|             launcherNote.save(); | ||||
|         } | ||||
|  | ||||
|         if (launcherNote.getParentBranches().length === 1) { | ||||
|             const branch = launcherNote.getParentBranches()[0]; | ||||
|  | ||||
|             if (branch.parentNoteId !== parentNoteId) { | ||||
|                 branchService.moveBranchToNote(branch, parentNoteId); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (opts.type === 'note') { | ||||
|             launcherNote.setRelation('target', opts.targetNoteId); | ||||
|         } else if (opts.type === 'script') { | ||||
|             launcherNote.setRelation('script', opts.scriptNoteId); | ||||
|         } else if (opts.type === 'customWidget') { | ||||
|             launcherNote.setRelation('widget', opts.widgetNoteId); | ||||
|         } else { | ||||
|             throw new Error(`Unrecognized launcher type '${opts.type}'`); | ||||
|         } | ||||
|  | ||||
|         if (opts.keyboardShortcut) { | ||||
|             launcherNote.setLabel('keyboardShortcut', opts.keyboardShortcut); | ||||
|         } else { | ||||
|             launcherNote.removeLabel('keyboardShortcut'); | ||||
|         } | ||||
|  | ||||
|         if (opts.icon) { | ||||
|             launcherNote.setLabel('iconClass', `bx ${opts.icon}`); | ||||
|         } else { | ||||
|             launcherNote.removeLabel('iconClass'); | ||||
|         } | ||||
|  | ||||
|         return {note: launcherNote}; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @param {string} noteId | ||||
|      * @param {string} format - either 'html' or 'markdown' | ||||
|      * @param {string} zipFilePath | ||||
|      * @returns {Promise<void>} | ||||
|      */ | ||||
|     this.exportSubtreeToZipFile = async (noteId, format, zipFilePath) => await exportService.exportToZipFile(noteId, format, zipFilePath); | ||||
|  | ||||
|     /** | ||||
|      * Executes given anonymous function on the frontend(s). | ||||
|      * Internally, this serializes the anonymous function into string and sends it to frontend(s) via WebSocket. | ||||
|      * Note that there can be multiple connected frontend instances (e.g. in different tabs). In such case, all | ||||
|      * instances execute the given function. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} script - script to be executed on the frontend | ||||
|      * @param {Array.<?>} params - list of parameters to the anonymous function to be sent to frontend | ||||
|      * @returns {undefined} - no return value is provided. | ||||
|      */ | ||||
|     this.runOnFrontend = async (script, params = []) => { | ||||
|         if (typeof script === "function") { | ||||
|             script = script.toString(); | ||||
|         } | ||||
|  | ||||
|         ws.sendMessageToAllClients({ | ||||
|             type: 'execute-script', | ||||
|             script: script, | ||||
|             params: prepareParams(params), | ||||
|             startNoteId: this.startNote.noteId, | ||||
|             currentNoteId: this.currentNote.noteId, | ||||
|             originEntityName: "notes", // currently there's no other entity on the frontend which can trigger event | ||||
|             originEntityId: this.originEntity?.noteId || null | ||||
|         }); | ||||
|  | ||||
|         function prepareParams(params) { | ||||
|             if (!params) { | ||||
|                 return params; | ||||
|             } | ||||
|  | ||||
|             return params.map(p => { | ||||
|                 if (typeof p === "function") { | ||||
|                     return `!@#Function: ${p.toString()}`; | ||||
|                 } | ||||
|                 else { | ||||
|                     return p; | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Sync process can make data intermittently inconsistent. Scripts which require strong data consistency | ||||
|      * can use this function to wait for a possible sync process to finish and prevent new sync process from starting | ||||
|      * while it is running. | ||||
|      * | ||||
|      * Because this is an async process, the inner callback doesn't have automatic transaction handling, so in case | ||||
|      * you need to make some DB changes, you need to surround your call with api.transactional(...) | ||||
|      * | ||||
|      * @method | ||||
|      * @param {function} callback - function to be executed while sync process is not running | ||||
|      * @returns {Promise} - resolves once the callback is finished (callback is awaited) | ||||
|      */ | ||||
|     this.runOutsideOfSync = syncMutex.doExclusively; | ||||
|  | ||||
|     /** | ||||
|      * @method | ||||
|      * @param {string} backupName - If the backupName is e.g. "now", then the backup will be written to "backup-now.db" file | ||||
|      * @returns {Promise} - resolves once the backup is finished | ||||
|      */ | ||||
|     this.backupNow = backupService.backupNow; | ||||
|  | ||||
|     /** | ||||
|      * This object contains "at your risk" and "no BC guarantees" objects for advanced use cases. | ||||
|      * | ||||
|      * @property {Becca} becca - provides access to the backend in-memory object graph, see {@link https://github.com/zadam/trilium/blob/master/src/becca/becca.js} | ||||
|      */ | ||||
|     this.__private = { | ||||
|         becca | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = BackendScriptApi; | ||||
| </code></pre> | ||||
|         </article> | ||||
|     </section> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| </div> | ||||
|  | ||||
| <nav> | ||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> | ||||
| </nav> | ||||
|  | ||||
| <br class="clear"> | ||||
|  | ||||
| <footer> | ||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> | ||||
| </footer> | ||||
|  | ||||
| <script> prettyPrint(); </script> | ||||
| <script src="scripts/linenumber.js"> </script> | ||||
| </body> | ||||
| </html> | ||||
| @@ -1,436 +0,0 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <title>JSDoc: Source: services/sql.js</title> | ||||
|  | ||||
|     <script src="scripts/prettify/prettify.js"> </script> | ||||
|     <script src="scripts/prettify/lang-css.js"> </script> | ||||
|     <!--[if lt IE 9]> | ||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> | ||||
|     <![endif]--> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | ||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|  | ||||
| <div id="main"> | ||||
|  | ||||
|     <h1 class="page-title">Source: services/sql.js</h1> | ||||
|  | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
|      | ||||
|     <section> | ||||
|         <article> | ||||
|             <pre class="prettyprint source linenums"><code>"use strict"; | ||||
|  | ||||
| /** | ||||
|  * @module sql | ||||
|  */ | ||||
|  | ||||
| const log = require('./log'); | ||||
| const Database = require('better-sqlite3'); | ||||
| const dataDir = require('./data_dir'); | ||||
| const cls = require('./cls'); | ||||
| const fs = require("fs-extra"); | ||||
|  | ||||
| const dbConnection = new Database(dataDir.DOCUMENT_PATH); | ||||
| dbConnection.pragma('journal_mode = WAL'); | ||||
|  | ||||
| const LOG_ALL_QUERIES = false; | ||||
|  | ||||
| [`exit`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `SIGTERM`].forEach(eventType => { | ||||
|     process.on(eventType, () => { | ||||
|         if (dbConnection) { | ||||
|             // closing connection is especially important to fold -wal file into the main DB file | ||||
|             // (see https://sqlite.org/tempfiles.html for details) | ||||
|             dbConnection.close(); | ||||
|         } | ||||
|     }); | ||||
| }); | ||||
|  | ||||
| function insert(tableName, rec, replace = false) { | ||||
|     const keys = Object.keys(rec || {}); | ||||
|     if (keys.length === 0) { | ||||
|         log.error(`Can't insert empty object into table ${tableName}`); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const columns = keys.join(", "); | ||||
|     const questionMarks = keys.map(p => "?").join(", "); | ||||
|  | ||||
|     const query = `INSERT | ||||
|     ${replace ? "OR REPLACE" : ""} INTO | ||||
|     ${tableName} | ||||
|     ( | ||||
|     ${columns} | ||||
|     ) | ||||
|     VALUES (${questionMarks})`; | ||||
|  | ||||
|     const res = execute(query, Object.values(rec)); | ||||
|  | ||||
|     return res ? res.lastInsertRowid : null; | ||||
| } | ||||
|  | ||||
| function replace(tableName, rec) { | ||||
|     return insert(tableName, rec, true); | ||||
| } | ||||
|  | ||||
| function upsert(tableName, primaryKey, rec) { | ||||
|     const keys = Object.keys(rec || {}); | ||||
|     if (keys.length === 0) { | ||||
|         log.error(`Can't upsert empty object into table ${tableName}`); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const columns = keys.join(", "); | ||||
|  | ||||
|     const questionMarks = keys.map(colName => `@${colName}`).join(", "); | ||||
|  | ||||
|     const updateMarks = keys.map(colName => `${colName} = @${colName}`).join(", "); | ||||
|  | ||||
|     const query = `INSERT INTO ${tableName} (${columns}) VALUES (${questionMarks})  | ||||
|                    ON CONFLICT (${primaryKey}) DO UPDATE SET ${updateMarks}`; | ||||
|  | ||||
|     for (const idx in rec) { | ||||
|         if (rec[idx] === true || rec[idx] === false) { | ||||
|             rec[idx] = rec[idx] ? 1 : 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     execute(query, rec); | ||||
| } | ||||
|  | ||||
| const statementCache = {}; | ||||
|  | ||||
| function stmt(sql) { | ||||
|     if (!(sql in statementCache)) { | ||||
|         statementCache[sql] = dbConnection.prepare(sql); | ||||
|     } | ||||
|  | ||||
|     return statementCache[sql]; | ||||
| } | ||||
|  | ||||
| function getRow(query, params = []) { | ||||
|     return wrap(query, s => s.get(params)); | ||||
| } | ||||
|  | ||||
| function getRowOrNull(query, params = []) { | ||||
|     const all = getRows(query, params); | ||||
|  | ||||
|     return all.length > 0 ? all[0] : null; | ||||
| } | ||||
|  | ||||
| function getValue(query, params = []) { | ||||
|     return wrap(query, s => s.pluck().get(params)); | ||||
| } | ||||
|  | ||||
| // smaller values can result in better performance due to better usage of statement cache | ||||
| const PARAM_LIMIT = 100; | ||||
|  | ||||
| function getManyRows(query, params) { | ||||
|     let results = []; | ||||
|  | ||||
|     while (params.length > 0) { | ||||
|         const curParams = params.slice(0, Math.min(params.length, PARAM_LIMIT)); | ||||
|         params = params.slice(curParams.length); | ||||
|  | ||||
|         const curParamsObj = {}; | ||||
|  | ||||
|         let j = 1; | ||||
|         for (const param of curParams) { | ||||
|             curParamsObj['param' + j++] = param; | ||||
|         } | ||||
|  | ||||
|         let i = 1; | ||||
|         const questionMarks = curParams.map(() => ":param" + i++).join(","); | ||||
|         const curQuery = query.replace(/\?\?\?/g, questionMarks); | ||||
|  | ||||
|         const statement = curParams.length === PARAM_LIMIT | ||||
|             ? stmt(curQuery) | ||||
|             : dbConnection.prepare(curQuery); | ||||
|  | ||||
|         const subResults = statement.all(curParamsObj); | ||||
|         results = results.concat(subResults); | ||||
|     } | ||||
|  | ||||
|     return results; | ||||
| } | ||||
|  | ||||
| function getRows(query, params = []) { | ||||
|     return wrap(query, s => s.all(params)); | ||||
| } | ||||
|  | ||||
| function getRawRows(query, params = []) { | ||||
|     return wrap(query, s => s.raw().all(params)); | ||||
| } | ||||
|  | ||||
| function iterateRows(query, params = []) { | ||||
|     if (LOG_ALL_QUERIES) { | ||||
|         console.log(query); | ||||
|     } | ||||
|  | ||||
|     return stmt(query).iterate(params); | ||||
| } | ||||
|  | ||||
| function getMap(query, params = []) { | ||||
|     const map = {}; | ||||
|     const results = getRawRows(query, params); | ||||
|  | ||||
|     for (const row of results) { | ||||
|         map[row[0]] = row[1]; | ||||
|     } | ||||
|  | ||||
|     return map; | ||||
| } | ||||
|  | ||||
| function getColumn(query, params = []) { | ||||
|     return wrap(query, s => s.pluck().all(params)); | ||||
| } | ||||
|  | ||||
| function execute(query, params = []) { | ||||
|     return wrap(query, s => s.run(params)); | ||||
| } | ||||
|  | ||||
| function executeMany(query, params) { | ||||
|     if (LOG_ALL_QUERIES) { | ||||
|         console.log(query); | ||||
|     } | ||||
|  | ||||
|     while (params.length > 0) { | ||||
|         const curParams = params.slice(0, Math.min(params.length, PARAM_LIMIT)); | ||||
|         params = params.slice(curParams.length); | ||||
|  | ||||
|         const curParamsObj = {}; | ||||
|  | ||||
|         let j = 1; | ||||
|         for (const param of curParams) { | ||||
|             curParamsObj['param' + j++] = param; | ||||
|         } | ||||
|  | ||||
|         let i = 1; | ||||
|         const questionMarks = curParams.map(() => ":param" + i++).join(","); | ||||
|         const curQuery = query.replace(/\?\?\?/g, questionMarks); | ||||
|  | ||||
|         dbConnection.prepare(curQuery).run(curParamsObj); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function executeScript(query) { | ||||
|     if (LOG_ALL_QUERIES) { | ||||
|         console.log(query); | ||||
|     } | ||||
|  | ||||
|     return dbConnection.exec(query); | ||||
| } | ||||
|  | ||||
| function wrap(query, func) { | ||||
|     const startTimestamp = Date.now(); | ||||
|     let result; | ||||
|  | ||||
|     if (LOG_ALL_QUERIES) { | ||||
|         console.log(query); | ||||
|     } | ||||
|  | ||||
|     try { | ||||
|         result = func(stmt(query)); | ||||
|     } | ||||
|     catch (e) { | ||||
|         if (e.message.includes("The database connection is not open")) { | ||||
|             // this often happens on killing the app which puts these alerts in front of user | ||||
|             // in these cases error should be simply ignored. | ||||
|             console.log(e.message); | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         throw e; | ||||
|     } | ||||
|  | ||||
|     const milliseconds = Date.now() - startTimestamp; | ||||
|  | ||||
|     if (milliseconds >= 20 && !cls.isSlowQueryLoggingDisabled()) { | ||||
|         if (query.includes("WITH RECURSIVE")) { | ||||
|             log.info(`Slow recursive query took ${milliseconds}ms.`); | ||||
|         } | ||||
|         else { | ||||
|             log.info(`Slow query took ${milliseconds}ms: ${query.trim().replace(/\s+/g, " ")}`); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function transactional(func) { | ||||
|     try { | ||||
|         const ret = dbConnection.transaction(func).deferred(); | ||||
|  | ||||
|         if (!dbConnection.inTransaction) { // i.e. transaction was really committed (and not just savepoint released) | ||||
|             require('./ws').sendTransactionEntityChangesToAllClients(); | ||||
|         } | ||||
|  | ||||
|         return ret; | ||||
|     } | ||||
|     catch (e) { | ||||
|         const entityChangeIds = cls.getAndClearEntityChangeIds(); | ||||
|  | ||||
|         if (entityChangeIds.length > 0) { | ||||
|             log.info("Transaction rollback dirtied the becca, forcing reload."); | ||||
|  | ||||
|             require('../becca/becca_loader').load(); | ||||
|         } | ||||
|  | ||||
|         // the maxEntityChangeId has been incremented during failed transaction, need to recalculate | ||||
|         require('./entity_changes').recalculateMaxEntityChangeId(); | ||||
|  | ||||
|         throw e; | ||||
|     } | ||||
| } | ||||
|  | ||||
| function fillParamList(paramIds, truncate = true) { | ||||
|     if (paramIds.length === 0) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     if (truncate) { | ||||
|         execute("DELETE FROM param_list"); | ||||
|     } | ||||
|  | ||||
|     paramIds = Array.from(new Set(paramIds)); | ||||
|  | ||||
|     if (paramIds.length > 30000) { | ||||
|         fillParamList(paramIds.slice(30000), false); | ||||
|  | ||||
|         paramIds = paramIds.slice(0, 30000); | ||||
|     } | ||||
|  | ||||
|     // doing it manually to avoid this showing up on the sloq query list | ||||
|     const s = stmt(`INSERT INTO param_list VALUES ${paramIds.map(paramId => `(?)`).join(',')}`); | ||||
|  | ||||
|     s.run(paramIds); | ||||
| } | ||||
|  | ||||
| async function copyDatabase(targetFilePath) { | ||||
|     try { | ||||
|         fs.unlinkSync(targetFilePath); | ||||
|     } catch (e) { | ||||
|     } // unlink throws exception if the file did not exist | ||||
|  | ||||
|     await dbConnection.backup(targetFilePath); | ||||
| } | ||||
|  | ||||
| function disableSlowQueryLogging(cb) { | ||||
|     const orig = cls.isSlowQueryLoggingDisabled(); | ||||
|  | ||||
|     try { | ||||
|         cls.disableSlowQueryLogging(true); | ||||
|  | ||||
|         return cb(); | ||||
|     } | ||||
|     finally { | ||||
|         cls.disableSlowQueryLogging(orig); | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|     dbConnection, | ||||
|     insert, | ||||
|     replace, | ||||
|  | ||||
|     /** | ||||
|      * Get single value from the given query - first column from first returned row. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} query - SQL query with ? used as parameter placeholder | ||||
|      * @param {object[]} [params] - array of params if needed | ||||
|      * @returns [object] - single value | ||||
|      */ | ||||
|     getValue, | ||||
|  | ||||
|     /** | ||||
|      * Get first returned row. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} query - SQL query with ? used as parameter placeholder | ||||
|      * @param {object[]} [params] - array of params if needed | ||||
|      * @returns {object} - map of column name to column value | ||||
|      */ | ||||
|     getRow, | ||||
|     getRowOrNull, | ||||
|  | ||||
|     /** | ||||
|      * Get all returned rows. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} query - SQL query with ? used as parameter placeholder | ||||
|      * @param {object[]} [params] - array of params if needed | ||||
|      * @returns {object[]} - array of all rows, each row is a map of column name to column value | ||||
|      */ | ||||
|     getRows, | ||||
|     getRawRows, | ||||
|     iterateRows, | ||||
|     getManyRows, | ||||
|  | ||||
|     /** | ||||
|      * Get a map of first column mapping to second column. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} query - SQL query with ? used as parameter placeholder | ||||
|      * @param {object[]} [params] - array of params if needed | ||||
|      * @returns {object} - map of first column to second column | ||||
|      */ | ||||
|     getMap, | ||||
|  | ||||
|     /** | ||||
|      * Get a first column in an array. | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} query - SQL query with ? used as parameter placeholder | ||||
|      * @param {object[]} [params] - array of params if needed | ||||
|      * @returns {object[]} - array of first column of all returned rows | ||||
|      */ | ||||
|     getColumn, | ||||
|  | ||||
|     /** | ||||
|      * Execute SQL | ||||
|      * | ||||
|      * @method | ||||
|      * @param {string} query - SQL query with ? used as parameter placeholder | ||||
|      * @param {object[]} [params] - array of params if needed | ||||
|      */ | ||||
|     execute, | ||||
|     executeMany, | ||||
|     executeScript, | ||||
|     transactional, | ||||
|     upsert, | ||||
|     fillParamList, | ||||
|     copyDatabase, | ||||
|     disableSlowQueryLogging | ||||
| }; | ||||
| </code></pre> | ||||
|         </article> | ||||
|     </section> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| </div> | ||||
|  | ||||
| <nav> | ||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> | ||||
| </nav> | ||||
|  | ||||
| <br class="clear"> | ||||
|  | ||||
| <footer> | ||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> | ||||
| </footer> | ||||
|  | ||||
| <script> prettyPrint(); </script> | ||||
| <script src="scripts/linenumber.js"> </script> | ||||
| </body> | ||||
| </html> | ||||
| @@ -1,358 +0,0 @@ | ||||
| @font-face { | ||||
|     font-family: 'Open Sans'; | ||||
|     font-weight: normal; | ||||
|     font-style: normal; | ||||
|     src: url('../fonts/OpenSans-Regular-webfont.eot'); | ||||
|     src: | ||||
|         local('Open Sans'), | ||||
|         local('OpenSans'), | ||||
|         url('../fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'), | ||||
|         url('../fonts/OpenSans-Regular-webfont.woff') format('woff'), | ||||
|         url('../fonts/OpenSans-Regular-webfont.svg#open_sansregular') format('svg'); | ||||
| } | ||||
|  | ||||
| @font-face { | ||||
|     font-family: 'Open Sans Light'; | ||||
|     font-weight: normal; | ||||
|     font-style: normal; | ||||
|     src: url('../fonts/OpenSans-Light-webfont.eot'); | ||||
|     src: | ||||
|         local('Open Sans Light'), | ||||
|         local('OpenSans Light'), | ||||
|         url('../fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'), | ||||
|         url('../fonts/OpenSans-Light-webfont.woff') format('woff'), | ||||
|         url('../fonts/OpenSans-Light-webfont.svg#open_sanslight') format('svg'); | ||||
| } | ||||
|  | ||||
| html | ||||
| { | ||||
|     overflow: auto; | ||||
|     background-color: #fff; | ||||
|     font-size: 14px; | ||||
| } | ||||
|  | ||||
| body | ||||
| { | ||||
|     font-family: 'Open Sans', sans-serif; | ||||
|     line-height: 1.5; | ||||
|     color: #4d4e53; | ||||
|     background-color: white; | ||||
| } | ||||
|  | ||||
| a, a:visited, a:active { | ||||
|     color: #0095dd; | ||||
|     text-decoration: none; | ||||
| } | ||||
|  | ||||
| a:hover { | ||||
|     text-decoration: underline; | ||||
| } | ||||
|  | ||||
| header | ||||
| { | ||||
|     display: block; | ||||
|     padding: 0px 4px; | ||||
| } | ||||
|  | ||||
| tt, code, kbd, samp { | ||||
|     font-family: Consolas, Monaco, 'Andale Mono', monospace; | ||||
| } | ||||
|  | ||||
| .class-description { | ||||
|     font-size: 130%; | ||||
|     line-height: 140%; | ||||
|     margin-bottom: 1em; | ||||
|     margin-top: 1em; | ||||
| } | ||||
|  | ||||
| .class-description:empty { | ||||
|     margin: 0; | ||||
| } | ||||
|  | ||||
| #main { | ||||
|     float: left; | ||||
|     width: 70%; | ||||
| } | ||||
|  | ||||
| article dl { | ||||
|     margin-bottom: 40px; | ||||
| } | ||||
|  | ||||
| article img { | ||||
|   max-width: 100%; | ||||
| } | ||||
|  | ||||
| section | ||||
| { | ||||
|     display: block; | ||||
|     background-color: #fff; | ||||
|     padding: 12px 24px; | ||||
|     border-bottom: 1px solid #ccc; | ||||
|     margin-right: 30px; | ||||
| } | ||||
|  | ||||
| .variation { | ||||
|     display: none; | ||||
| } | ||||
|  | ||||
| .signature-attributes { | ||||
|     font-size: 60%; | ||||
|     color: #aaa; | ||||
|     font-style: italic; | ||||
|     font-weight: lighter; | ||||
| } | ||||
|  | ||||
| nav | ||||
| { | ||||
|     display: block; | ||||
|     float: right; | ||||
|     margin-top: 28px; | ||||
|     width: 30%; | ||||
|     box-sizing: border-box; | ||||
|     border-left: 1px solid #ccc; | ||||
|     padding-left: 16px; | ||||
| } | ||||
|  | ||||
| nav ul { | ||||
|     font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif; | ||||
|     font-size: 100%; | ||||
|     line-height: 17px; | ||||
|     padding: 0; | ||||
|     margin: 0; | ||||
|     list-style-type: none; | ||||
| } | ||||
|  | ||||
| nav ul a, nav ul a:visited, nav ul a:active { | ||||
|     font-family: Consolas, Monaco, 'Andale Mono', monospace; | ||||
|     line-height: 18px; | ||||
|     color: #4D4E53; | ||||
| } | ||||
|  | ||||
| nav h3 { | ||||
|     margin-top: 12px; | ||||
| } | ||||
|  | ||||
| nav li { | ||||
|     margin-top: 6px; | ||||
| } | ||||
|  | ||||
| footer { | ||||
|     display: block; | ||||
|     padding: 6px; | ||||
|     margin-top: 12px; | ||||
|     font-style: italic; | ||||
|     font-size: 90%; | ||||
| } | ||||
|  | ||||
| h1, h2, h3, h4 { | ||||
|     font-weight: 200; | ||||
|     margin: 0; | ||||
| } | ||||
|  | ||||
| h1 | ||||
| { | ||||
|     font-family: 'Open Sans Light', sans-serif; | ||||
|     font-size: 48px; | ||||
|     letter-spacing: -2px; | ||||
|     margin: 12px 24px 20px; | ||||
| } | ||||
|  | ||||
| h2, h3.subsection-title | ||||
| { | ||||
|     font-size: 30px; | ||||
|     font-weight: 700; | ||||
|     letter-spacing: -1px; | ||||
|     margin-bottom: 12px; | ||||
| } | ||||
|  | ||||
| h3 | ||||
| { | ||||
|     font-size: 24px; | ||||
|     letter-spacing: -0.5px; | ||||
|     margin-bottom: 12px; | ||||
| } | ||||
|  | ||||
| h4 | ||||
| { | ||||
|     font-size: 18px; | ||||
|     letter-spacing: -0.33px; | ||||
|     margin-bottom: 12px; | ||||
|     color: #4d4e53; | ||||
| } | ||||
|  | ||||
| h5, .container-overview .subsection-title | ||||
| { | ||||
|     font-size: 120%; | ||||
|     font-weight: bold; | ||||
|     letter-spacing: -0.01em; | ||||
|     margin: 8px 0 3px 0; | ||||
| } | ||||
|  | ||||
| h6 | ||||
| { | ||||
|     font-size: 100%; | ||||
|     letter-spacing: -0.01em; | ||||
|     margin: 6px 0 3px 0; | ||||
|     font-style: italic; | ||||
| } | ||||
|  | ||||
| table | ||||
| { | ||||
|     border-spacing: 0; | ||||
|     border: 0; | ||||
|     border-collapse: collapse; | ||||
| } | ||||
|  | ||||
| td, th | ||||
| { | ||||
|     border: 1px solid #ddd; | ||||
|     margin: 0px; | ||||
|     text-align: left; | ||||
|     vertical-align: top; | ||||
|     padding: 4px 6px; | ||||
|     display: table-cell; | ||||
| } | ||||
|  | ||||
| thead tr | ||||
| { | ||||
|     background-color: #ddd; | ||||
|     font-weight: bold; | ||||
| } | ||||
|  | ||||
| th { border-right: 1px solid #aaa; } | ||||
| tr > th:last-child { border-right: 1px solid #ddd; } | ||||
|  | ||||
| .ancestors, .attribs { color: #999; } | ||||
| .ancestors a, .attribs a | ||||
| { | ||||
|     color: #999 !important; | ||||
|     text-decoration: none; | ||||
| } | ||||
|  | ||||
| .clear | ||||
| { | ||||
|     clear: both; | ||||
| } | ||||
|  | ||||
| .important | ||||
| { | ||||
|     font-weight: bold; | ||||
|     color: #950B02; | ||||
| } | ||||
|  | ||||
| .yes-def { | ||||
|     text-indent: -1000px; | ||||
| } | ||||
|  | ||||
| .type-signature { | ||||
|     color: #aaa; | ||||
| } | ||||
|  | ||||
| .name, .signature { | ||||
|     font-family: Consolas, Monaco, 'Andale Mono', monospace; | ||||
| } | ||||
|  | ||||
| .details { margin-top: 14px; border-left: 2px solid #DDD; } | ||||
| .details dt { width: 120px; float: left; padding-left: 10px;  padding-top: 6px; } | ||||
| .details dd { margin-left: 70px; } | ||||
| .details ul { margin: 0; } | ||||
| .details ul { list-style-type: none; } | ||||
| .details li { margin-left: 30px; padding-top: 6px; } | ||||
| .details pre.prettyprint { margin: 0 } | ||||
| .details .object-value { padding-top: 0; } | ||||
|  | ||||
| .description { | ||||
|     margin-bottom: 1em; | ||||
|     margin-top: 1em; | ||||
| } | ||||
|  | ||||
| .code-caption | ||||
| { | ||||
|     font-style: italic; | ||||
|     font-size: 107%; | ||||
|     margin: 0; | ||||
| } | ||||
|  | ||||
| .source | ||||
| { | ||||
|     border: 1px solid #ddd; | ||||
|     width: 80%; | ||||
|     overflow: auto; | ||||
| } | ||||
|  | ||||
| .prettyprint.source { | ||||
|     width: inherit; | ||||
| } | ||||
|  | ||||
| .source code | ||||
| { | ||||
|     font-size: 100%; | ||||
|     line-height: 18px; | ||||
|     display: block; | ||||
|     padding: 4px 12px; | ||||
|     margin: 0; | ||||
|     background-color: #fff; | ||||
|     color: #4D4E53; | ||||
| } | ||||
|  | ||||
| .prettyprint code span.line | ||||
| { | ||||
|   display: inline-block; | ||||
| } | ||||
|  | ||||
| .prettyprint.linenums | ||||
| { | ||||
|   padding-left: 70px; | ||||
|   -webkit-user-select: none; | ||||
|   -moz-user-select: none; | ||||
|   -ms-user-select: none; | ||||
|   user-select: none; | ||||
| } | ||||
|  | ||||
| .prettyprint.linenums ol | ||||
| { | ||||
|   padding-left: 0; | ||||
| } | ||||
|  | ||||
| .prettyprint.linenums li | ||||
| { | ||||
|   border-left: 3px #ddd solid; | ||||
| } | ||||
|  | ||||
| .prettyprint.linenums li.selected, | ||||
| .prettyprint.linenums li.selected * | ||||
| { | ||||
|   background-color: lightyellow; | ||||
| } | ||||
|  | ||||
| .prettyprint.linenums li * | ||||
| { | ||||
|   -webkit-user-select: text; | ||||
|   -moz-user-select: text; | ||||
|   -ms-user-select: text; | ||||
|   user-select: text; | ||||
| } | ||||
|  | ||||
| .params .name, .props .name, .name code { | ||||
|     color: #4D4E53; | ||||
|     font-family: Consolas, Monaco, 'Andale Mono', monospace; | ||||
|     font-size: 100%; | ||||
| } | ||||
|  | ||||
| .params td.description > p:first-child, | ||||
| .props td.description > p:first-child | ||||
| { | ||||
|     margin-top: 0; | ||||
|     padding-top: 0; | ||||
| } | ||||
|  | ||||
| .params td.description > p:last-child, | ||||
| .props td.description > p:last-child | ||||
| { | ||||
|     margin-bottom: 0; | ||||
|     padding-bottom: 0; | ||||
| } | ||||
|  | ||||
| .disabled { | ||||
|     color: #454545; | ||||
| } | ||||
| @@ -1,111 +0,0 @@ | ||||
| /* JSDoc prettify.js theme */ | ||||
|  | ||||
| /* plain text */ | ||||
| .pln { | ||||
|   color: #000000; | ||||
|   font-weight: normal; | ||||
|   font-style: normal; | ||||
| } | ||||
|  | ||||
| /* string content */ | ||||
| .str { | ||||
|   color: #006400; | ||||
|   font-weight: normal; | ||||
|   font-style: normal; | ||||
| } | ||||
|  | ||||
| /* a keyword */ | ||||
| .kwd { | ||||
|   color: #000000; | ||||
|   font-weight: bold; | ||||
|   font-style: normal; | ||||
| } | ||||
|  | ||||
| /* a comment */ | ||||
| .com { | ||||
|   font-weight: normal; | ||||
|   font-style: italic; | ||||
| } | ||||
|  | ||||
| /* a type name */ | ||||
| .typ { | ||||
|   color: #000000; | ||||
|   font-weight: normal; | ||||
|   font-style: normal; | ||||
| } | ||||
|  | ||||
| /* a literal value */ | ||||
| .lit { | ||||
|   color: #006400; | ||||
|   font-weight: normal; | ||||
|   font-style: normal; | ||||
| } | ||||
|  | ||||
| /* punctuation */ | ||||
| .pun { | ||||
|   color: #000000; | ||||
|   font-weight: bold; | ||||
|   font-style: normal; | ||||
| } | ||||
|  | ||||
| /* lisp open bracket */ | ||||
| .opn { | ||||
|   color: #000000; | ||||
|   font-weight: bold; | ||||
|   font-style: normal; | ||||
| } | ||||
|  | ||||
| /* lisp close bracket */ | ||||
| .clo { | ||||
|   color: #000000; | ||||
|   font-weight: bold; | ||||
|   font-style: normal; | ||||
| } | ||||
|  | ||||
| /* a markup tag name */ | ||||
| .tag { | ||||
|   color: #006400; | ||||
|   font-weight: normal; | ||||
|   font-style: normal; | ||||
| } | ||||
|  | ||||
| /* a markup attribute name */ | ||||
| .atn { | ||||
|   color: #006400; | ||||
|   font-weight: normal; | ||||
|   font-style: normal; | ||||
| } | ||||
|  | ||||
| /* a markup attribute value */ | ||||
| .atv { | ||||
|   color: #006400; | ||||
|   font-weight: normal; | ||||
|   font-style: normal; | ||||
| } | ||||
|  | ||||
| /* a declaration */ | ||||
| .dec { | ||||
|   color: #000000; | ||||
|   font-weight: bold; | ||||
|   font-style: normal; | ||||
| } | ||||
|  | ||||
| /* a variable name */ | ||||
| .var { | ||||
|   color: #000000; | ||||
|   font-weight: normal; | ||||
|   font-style: normal; | ||||
| } | ||||
|  | ||||
| /* a function name */ | ||||
| .fun { | ||||
|   color: #000000; | ||||
|   font-weight: bold; | ||||
|   font-style: normal; | ||||
| } | ||||
|  | ||||
| /* Specify class=linenums on a pre to get line numbering */ | ||||
| ol.linenums { | ||||
|   margin-top: 0; | ||||
|   margin-bottom: 0; | ||||
| } | ||||
| @@ -1,132 +0,0 @@ | ||||
| /* Tomorrow Theme */ | ||||
| /* Original theme - https://github.com/chriskempson/tomorrow-theme */ | ||||
| /* Pretty printing styles. Used with prettify.js. */ | ||||
| /* SPAN elements with the classes below are added by prettyprint. */ | ||||
| /* plain text */ | ||||
| .pln { | ||||
|   color: #4d4d4c; } | ||||
|  | ||||
| @media screen { | ||||
|   /* string content */ | ||||
|   .str { | ||||
|     color: #718c00; } | ||||
|  | ||||
|   /* a keyword */ | ||||
|   .kwd { | ||||
|     color: #8959a8; } | ||||
|  | ||||
|   /* a comment */ | ||||
|   .com { | ||||
|     color: #8e908c; } | ||||
|  | ||||
|   /* a type name */ | ||||
|   .typ { | ||||
|     color: #4271ae; } | ||||
|  | ||||
|   /* a literal value */ | ||||
|   .lit { | ||||
|     color: #f5871f; } | ||||
|  | ||||
|   /* punctuation */ | ||||
|   .pun { | ||||
|     color: #4d4d4c; } | ||||
|  | ||||
|   /* lisp open bracket */ | ||||
|   .opn { | ||||
|     color: #4d4d4c; } | ||||
|  | ||||
|   /* lisp close bracket */ | ||||
|   .clo { | ||||
|     color: #4d4d4c; } | ||||
|  | ||||
|   /* a markup tag name */ | ||||
|   .tag { | ||||
|     color: #c82829; } | ||||
|  | ||||
|   /* a markup attribute name */ | ||||
|   .atn { | ||||
|     color: #f5871f; } | ||||
|  | ||||
|   /* a markup attribute value */ | ||||
|   .atv { | ||||
|     color: #3e999f; } | ||||
|  | ||||
|   /* a declaration */ | ||||
|   .dec { | ||||
|     color: #f5871f; } | ||||
|  | ||||
|   /* a variable name */ | ||||
|   .var { | ||||
|     color: #c82829; } | ||||
|  | ||||
|   /* a function name */ | ||||
|   .fun { | ||||
|     color: #4271ae; } } | ||||
| /* Use higher contrast and text-weight for printable form. */ | ||||
| @media print, projection { | ||||
|   .str { | ||||
|     color: #060; } | ||||
|  | ||||
|   .kwd { | ||||
|     color: #006; | ||||
|     font-weight: bold; } | ||||
|  | ||||
|   .com { | ||||
|     color: #600; | ||||
|     font-style: italic; } | ||||
|  | ||||
|   .typ { | ||||
|     color: #404; | ||||
|     font-weight: bold; } | ||||
|  | ||||
|   .lit { | ||||
|     color: #044; } | ||||
|  | ||||
|   .pun, .opn, .clo { | ||||
|     color: #440; } | ||||
|  | ||||
|   .tag { | ||||
|     color: #006; | ||||
|     font-weight: bold; } | ||||
|  | ||||
|   .atn { | ||||
|     color: #404; } | ||||
|  | ||||
|   .atv { | ||||
|     color: #060; } } | ||||
| /* Style */ | ||||
| /* | ||||
| pre.prettyprint { | ||||
|   background: white; | ||||
|   font-family: Consolas, Monaco, 'Andale Mono', monospace; | ||||
|   font-size: 12px; | ||||
|   line-height: 1.5; | ||||
|   border: 1px solid #ccc; | ||||
|   padding: 10px; } | ||||
| */ | ||||
|  | ||||
| /* Specify class=linenums on a pre to get line numbering */ | ||||
| ol.linenums { | ||||
|   margin-top: 0; | ||||
|   margin-bottom: 0; } | ||||
|  | ||||
| /* IE indents via margin-left */ | ||||
| li.L0, | ||||
| li.L1, | ||||
| li.L2, | ||||
| li.L3, | ||||
| li.L4, | ||||
| li.L5, | ||||
| li.L6, | ||||
| li.L7, | ||||
| li.L8, | ||||
| li.L9 { | ||||
|   /* */ } | ||||
|  | ||||
| /* Alternate shading for lines */ | ||||
| li.L1, | ||||
| li.L3, | ||||
| li.L5, | ||||
| li.L7, | ||||
| li.L9 { | ||||
|   /* */ } | ||||