mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	Compare commits
	
		
			16 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 21e77c83fc | ||
|  | b0310e34e2 | ||
|  | 761c51069a | ||
|  | 4dc285d84f | ||
|  | a1402c7c66 | ||
|  | 6ba3e5ab7f | ||
|  | f740e52ebf | ||
|  | e9454e4db7 | ||
|  | bfc7570e14 | ||
|  | 5de92171a7 | ||
|  | 29c5e394ab | ||
|  | 07b3d11fe5 | ||
|  | 67663fba50 | ||
|  | 995ebbf577 | ||
|  | d0e6be3e0c | ||
|  | 01370a5968 | 
							
								
								
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "trilium", |   "name": "trilium", | ||||||
|   "version": "0.37.5", |   "version": "0.37.7", | ||||||
|   "lockfileVersion": 1, |   "lockfileVersion": 1, | ||||||
|   "requires": true, |   "requires": true, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|   "name": "trilium", |   "name": "trilium", | ||||||
|   "productName": "Trilium Notes", |   "productName": "Trilium Notes", | ||||||
|   "description": "Trilium Notes", |   "description": "Trilium Notes", | ||||||
|   "version": "0.37.6", |   "version": "0.37.8", | ||||||
|   "license": "AGPL-3.0-only", |   "license": "AGPL-3.0-only", | ||||||
|   "main": "electron.js", |   "main": "electron.js", | ||||||
|   "bin": { |   "bin": { | ||||||
|   | |||||||
| @@ -334,6 +334,11 @@ class Note extends Entity { | |||||||
|         // we order by noteId so that attributes from same note stay together. Actual noteId ordering doesn't matter. |         // we order by noteId so that attributes from same note stay together. Actual noteId ordering doesn't matter. | ||||||
|  |  | ||||||
|         const filteredAttributes = attributes.filter((attr, index) => { |         const filteredAttributes = attributes.filter((attr, index) => { | ||||||
|  |             // if this exact attribute already appears then don't include it (can happen via cloning) | ||||||
|  |             if (attributes.findIndex(it => it.attributeId === attr.attributeId) !== index) { | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |  | ||||||
|             if (attr.isDefinition()) { |             if (attr.isDefinition()) { | ||||||
|                 const firstDefinitionIndex = attributes.findIndex(el => el.type === attr.type && el.name === attr.name); |                 const firstDefinitionIndex = attributes.findIndex(el => el.type === attr.type && el.name === attr.name); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -78,7 +78,7 @@ window.onerror = function (msg, url, lineNo, columnNo, error) { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| for (const appCssNoteId of window.appCssNoteIds) { | for (const appCssNoteId of window.appCssNoteIds) { | ||||||
|     cssLoader.requireCss(`/api/notes/download/${appCssNoteId}`); |     cssLoader.requireCss(`api/notes/download/${appCssNoteId}`); | ||||||
| } | } | ||||||
|  |  | ||||||
| const wikiBaseUrl = "https://github.com/zadam/trilium/wiki/"; | const wikiBaseUrl = "https://github.com/zadam/trilium/wiki/"; | ||||||
|   | |||||||
| @@ -131,7 +131,7 @@ export default class ApperanceOptions { | |||||||
|             if (noteId) { |             if (noteId) { | ||||||
|                 // make sure the CSS is loaded |                 // make sure the CSS is loaded | ||||||
|                 // if the CSS has been loaded and then updated then the changes won't take effect though |                 // if the CSS has been loaded and then updated then the changes won't take effect though | ||||||
|                 cssLoader.requireCss(`/api/notes/download/${noteId}`); |                 cssLoader.requireCss(`api/notes/download/${noteId}`); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             this.$body.addClass("theme-" + newTheme); |             this.$body.addClass("theme-" + newTheme); | ||||||
|   | |||||||
| @@ -411,6 +411,10 @@ div.ui-tooltip { | |||||||
|     height: 150px; |     height: 150px; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #sql-console-query .CodeMirror-scroll { | ||||||
|  |     min-height: inherit !important; | ||||||
|  | } | ||||||
|  |  | ||||||
| .btn { | .btn { | ||||||
|     border-radius: var(--button-border-radius); |     border-radius: var(--button-border-radius); | ||||||
| } | } | ||||||
| @@ -460,9 +464,10 @@ button.icon-button { | |||||||
|     margin: auto; |     margin: auto; | ||||||
|     /* setting the display to block since "table" doesn't support scrolling */ |     /* setting the display to block since "table" doesn't support scrolling */ | ||||||
|     display: block; |     display: block; | ||||||
|     flex-basis: content; |     /** flex-basis: content; - use once "content" is implemented by chrome */ | ||||||
|     flex-shrink: 1; |     flex-shrink: 0; | ||||||
|     flex-grow: 0; |     flex-grow: 0; | ||||||
|  |     max-height: 30%; | ||||||
|     overflow: auto; |     overflow: auto; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,7 +18,10 @@ async function anonymize() { | |||||||
|  |  | ||||||
|     await db.run("UPDATE notes SET title = 'title'"); |     await db.run("UPDATE notes SET title = 'title'"); | ||||||
|     await db.run("UPDATE note_contents SET content = 'text'"); |     await db.run("UPDATE note_contents SET content = 'text'"); | ||||||
|     await db.run("UPDATE note_revisions SET title = 'title', content = 'text'"); |     await db.run("UPDATE note_revisions SET title = 'title'"); | ||||||
|  |     await db.run("UPDATE note_revision_contents SET content = 'title'"); | ||||||
|  |     await db.run("UPDATE attributes SET name = 'name', value = 'value' WHERE type = 'label'"); | ||||||
|  |     await db.run("UPDATE attributes SET name = 'name' WHERE type = 'relation'"); | ||||||
|     await db.run("UPDATE branches SET prefix = 'prefix' WHERE prefix IS NOT NULL"); |     await db.run("UPDATE branches SET prefix = 'prefix' WHERE prefix IS NOT NULL"); | ||||||
|     await db.run(`UPDATE options SET value = 'anonymized' WHERE name IN  |     await db.run(`UPDATE options SET value = 'anonymized' WHERE name IN  | ||||||
|                     ('documentSecret', 'encryptedDataKey', 'passwordVerificationHash',  |                     ('documentSecret', 'encryptedDataKey', 'passwordVerificationHash',  | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| module.exports = { buildDate:"2019-11-26T22:50:08+01:00", buildRevision: "5193f073e9e55f5440fe2e71fbd2cdfcdb2d2c6b" }; | module.exports = { buildDate:"2019-12-03T22:31:20+01:00", buildRevision: "b0310e34e2c6f023cc8190310ff63d840157f6cc" }; | ||||||
|   | |||||||
| @@ -626,12 +626,31 @@ async function runAllChecks() { | |||||||
|     return !unrecoveredConsistencyErrors; |     return !unrecoveredConsistencyErrors; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | async function showEntityStat(name, query) { | ||||||
|  |     const map = await sql.getMap(query); | ||||||
|  |  | ||||||
|  |     map[0] = map[0] || 0; | ||||||
|  |     map[1] = map[1] || 0; | ||||||
|  |  | ||||||
|  |     log.info(`${name} deleted: ${map[1]}, not deleted ${map[0]}`); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function runDbDiagnostics() { | ||||||
|  |     await showEntityStat("Notes", `SELECT isDeleted, count(noteId) FROM notes GROUP BY isDeleted`); | ||||||
|  |     await showEntityStat("Note revisions", `SELECT isErased, count(noteRevisionId) FROM note_revisions GROUP BY isErased`); | ||||||
|  |     await showEntityStat("Branches", `SELECT isDeleted, count(branchId) FROM branches GROUP BY isDeleted`); | ||||||
|  |     await showEntityStat("Attributes", `SELECT isDeleted, count(attributeId) FROM attributes GROUP BY isDeleted`); | ||||||
|  |     await showEntityStat("API tokens", `SELECT isDeleted, count(apiTokenId) FROM api_tokens GROUP BY isDeleted`); | ||||||
|  | } | ||||||
|  |  | ||||||
| async function runChecks() { | async function runChecks() { | ||||||
|     let elapsedTimeMs; |     let elapsedTimeMs; | ||||||
|  |  | ||||||
|     await syncMutexService.doExclusively(async () => { |     await syncMutexService.doExclusively(async () => { | ||||||
|         const startTime = new Date(); |         const startTime = new Date(); | ||||||
|  |  | ||||||
|  |         await runDbDiagnostics(); | ||||||
|  |  | ||||||
|         await runAllChecks(); |         await runAllChecks(); | ||||||
|  |  | ||||||
|         elapsedTimeMs = Date.now() - startTime.getTime(); |         elapsedTimeMs = Date.now() - startTime.getTime(); | ||||||
| @@ -663,7 +682,7 @@ sqlInit.dbReady.then(() => { | |||||||
|     setInterval(cls.wrap(runChecks), 60 * 60 * 1000); |     setInterval(cls.wrap(runChecks), 60 * 60 * 1000); | ||||||
|  |  | ||||||
|     // kickoff checks soon after startup (to not block the initial load) |     // kickoff checks soon after startup (to not block the initial load) | ||||||
|     setTimeout(cls.wrap(runChecks), 10 * 1000); |     setTimeout(cls.wrap(runChecks), 20 * 1000); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| module.exports = {}; | module.exports = {}; | ||||||
| @@ -81,7 +81,7 @@ eventService.subscribe(eventService.CHILD_NOTE_CREATED, async ({ parentNote, chi | |||||||
| async function processInverseRelations(entityName, entity, handler) { | async function processInverseRelations(entityName, entity, handler) { | ||||||
|     if (entityName === 'attributes' && entity.type === 'relation') { |     if (entityName === 'attributes' && entity.type === 'relation') { | ||||||
|         const note = await entity.getNote(); |         const note = await entity.getNote(); | ||||||
|         const attributes = (await note.getAttributes(entity.name)).filter(relation => relation.type === 'relation-definition'); |         const attributes = (await note.getOwnedAttributes(entity.name)).filter(relation => relation.type === 'relation-definition'); | ||||||
|  |  | ||||||
|         for (const attribute of attributes) { |         for (const attribute of attributes) { | ||||||
|             const definition = attribute.value; |             const definition = attribute.value; | ||||||
|   | |||||||
| @@ -12,9 +12,7 @@ const imageminGifLossy = require('imagemin-giflossy'); | |||||||
| const jimp = require('jimp'); | const jimp = require('jimp'); | ||||||
| const imageType = require('image-type'); | const imageType = require('image-type'); | ||||||
| const sanitizeFilename = require('sanitize-filename'); | const sanitizeFilename = require('sanitize-filename'); | ||||||
| const dateUtils = require('./date_utils'); |  | ||||||
| const noteRevisionService = require('./note_revisions.js'); | const noteRevisionService = require('./note_revisions.js'); | ||||||
| const NoteRevision = require("../entities/note_revision"); |  | ||||||
|  |  | ||||||
| async function processImage(uploadBuffer, originalName, shrinkImageSwitch) { | async function processImage(uploadBuffer, originalName, shrinkImageSwitch) { | ||||||
|     const origImageFormat = imageType(uploadBuffer); |     const origImageFormat = imageType(uploadBuffer); | ||||||
|   | |||||||
| @@ -258,7 +258,8 @@ async function importTar(taskContext, fileBuffer, importRootNote) { | |||||||
|             content = content.toString("UTF-8"); |             content = content.toString("UTF-8"); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if ((noteMeta && noteMeta.format === 'markdown') || (!noteMeta && ['text/markdown', 'text/x-markdown'].includes(mime))) { |         if ((noteMeta && noteMeta.format === 'markdown') | ||||||
|  |             || (!noteMeta && taskContext.data.textImportedAsText && ['text/markdown', 'text/x-markdown'].includes(mime))) { | ||||||
|             const parsed = mdReader.parse(content); |             const parsed = mdReader.parse(content); | ||||||
|             content = mdWriter.render(parsed); |             content = mdWriter.render(parsed); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -43,9 +43,6 @@ async function migrate() { | |||||||
|         try { |         try { | ||||||
|             log.info("Attempting migration to version " + mig.dbVersion); |             log.info("Attempting migration to version " + mig.dbVersion); | ||||||
|  |  | ||||||
|             // needs to happen outside of the transaction (otherwise it's a NO-OP) |  | ||||||
|             await sql.execute("PRAGMA foreign_keys = OFF"); |  | ||||||
|  |  | ||||||
|             await sql.transactional(async () => { |             await sql.transactional(async () => { | ||||||
|                 if (mig.type === 'sql') { |                 if (mig.type === 'sql') { | ||||||
|                     const migrationSql = fs.readFileSync(resourceDir.MIGRATIONS_DIR + "/" + mig.file).toString('utf8'); |                     const migrationSql = fs.readFileSync(resourceDir.MIGRATIONS_DIR + "/" + mig.file).toString('utf8'); | ||||||
| @@ -76,10 +73,6 @@ async function migrate() { | |||||||
|  |  | ||||||
|             utils.crash(); |             utils.crash(); | ||||||
|         } |         } | ||||||
|         finally { |  | ||||||
|             // make sure foreign keys are enabled even if migration script disables them |  | ||||||
|             await sql.execute("PRAGMA foreign_keys = ON"); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (await sqlInit.isDbUpToDate()) { |     if (await sqlInit.isDbUpToDate()) { | ||||||
|   | |||||||
| @@ -7,10 +7,6 @@ const dateUtils = require('../services/date_utils'); | |||||||
|  * @param {Note} note |  * @param {Note} note | ||||||
|  */ |  */ | ||||||
| async function protectNoteRevisions(note) { | async function protectNoteRevisions(note) { | ||||||
|     if (await note.hasLabel('disableVersioning')) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     for (const revision of await note.getRevisions()) { |     for (const revision of await note.getRevisions()) { | ||||||
|         if (note.isProtected !== revision.isProtected) { |         if (note.isProtected !== revision.isProtected) { | ||||||
|             const content = await revision.getContent(); |             const content = await revision.getContent(); | ||||||
| @@ -30,6 +26,10 @@ async function protectNoteRevisions(note) { | |||||||
|  * @return {NoteRevision} |  * @return {NoteRevision} | ||||||
|  */ |  */ | ||||||
| async function createNoteRevision(note) { | async function createNoteRevision(note) { | ||||||
|  |     if (await note.hasLabel("disableVersioning")) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const noteRevision = await new NoteRevision({ |     const noteRevision = await new NoteRevision({ | ||||||
|         noteId: note.noteId, |         noteId: note.noteId, | ||||||
|         // title and text should be decrypted now |         // title and text should be decrypted now | ||||||
|   | |||||||
| @@ -117,7 +117,7 @@ async function createNewNote(parentNoteId, noteData) { | |||||||
|         isExpanded: !!noteData.isExpanded |         isExpanded: !!noteData.isExpanded | ||||||
|     }).save(); |     }).save(); | ||||||
|  |  | ||||||
|     for (const attr of await parentNote.getAttributes()) { |     for (const attr of await parentNote.getOwnedAttributes()) { | ||||||
|         if (attr.name.startsWith("child:")) { |         if (attr.name.startsWith("child:")) { | ||||||
|             await new Attribute({ |             await new Attribute({ | ||||||
|                noteId: note.noteId, |                noteId: note.noteId, | ||||||
| @@ -308,8 +308,7 @@ async function saveLinks(note, content) { | |||||||
| } | } | ||||||
|  |  | ||||||
| async function saveNoteRevision(note) { | async function saveNoteRevision(note) { | ||||||
|     // files and images are immutable, they can't be updated |     // files and images are versioned separately | ||||||
|     // but we don't even version titles which is probably not correct |  | ||||||
|     if (note.type === 'file' || note.type === 'image' || await note.hasLabel('disableVersioning')) { |     if (note.type === 'file' || note.type === 'image' || await note.hasLabel('disableVersioning')) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| @@ -480,7 +479,7 @@ async function eraseDeletedNotes() { | |||||||
|         SET content = NULL, |         SET content = NULL, | ||||||
|             utcDateModified = '${utcNowDateTime}' |             utcDateModified = '${utcNowDateTime}' | ||||||
|         WHERE noteRevisionId IN  |         WHERE noteRevisionId IN  | ||||||
|             (SELECT noteRevisionId FROM note_revisions WHERE isErased = 0 AND noteId IN ((???)))`, noteIdsToErase); |             (SELECT noteRevisionId FROM note_revisions WHERE isErased = 0 AND noteId IN (???))`, noteIdsToErase); | ||||||
|  |  | ||||||
|     await sql.executeMany(` |     await sql.executeMany(` | ||||||
|         UPDATE note_revisions  |         UPDATE note_revisions  | ||||||
| @@ -514,7 +513,7 @@ async function duplicateNote(noteId, parentNoteId) { | |||||||
|         notePosition: origBranch ? origBranch.notePosition + 1 : null |         notePosition: origBranch ? origBranch.notePosition + 1 : null | ||||||
|     }).save(); |     }).save(); | ||||||
|  |  | ||||||
|     for (const attribute of await origNote.getAttributes()) { |     for (const attribute of await origNote.getOwnedAttributes()) { | ||||||
|         const attr = new Attribute(attribute); |         const attr = new Attribute(attribute); | ||||||
|         attr.attributeId = undefined; // force creation of new attribute |         attr.attributeId = undefined; // force creation of new attribute | ||||||
|         attr.noteId = newNote.noteId; |         attr.noteId = newNote.noteId; | ||||||
|   | |||||||
| @@ -57,8 +57,6 @@ async function initDbConnection() { | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         await sql.execute("PRAGMA foreign_keys = ON"); |  | ||||||
|  |  | ||||||
|         const currentDbVersion = await getDbVersion(); |         const currentDbVersion = await getDbVersion(); | ||||||
|  |  | ||||||
|         if (currentDbVersion > appInfo.dbVersion) { |         if (currentDbVersion > appInfo.dbVersion) { | ||||||
| @@ -175,9 +173,11 @@ async function isDbUpToDate() { | |||||||
| } | } | ||||||
|  |  | ||||||
| async function dbInitialized() { | async function dbInitialized() { | ||||||
|     await optionService.setOption('initialized', 'true'); |     if (!await isDbInitialized()) { | ||||||
|  |         await optionService.setOption('initialized', 'true'); | ||||||
|  |  | ||||||
|     await initDbConnection(); |         await initDbConnection(); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| dbReady.then(async () => { | dbReady.then(async () => { | ||||||
|   | |||||||
| @@ -1,48 +1,32 @@ | |||||||
| const fs = require('fs'); | /** | ||||||
| const dataDir = require('../services/data_dir'); |  * Usage: node src/tools/generate_document.js 1000 | ||||||
|  |  * will create 1000 new notes and some clones into a current document.db | ||||||
| fs.unlinkSync(dataDir.DOCUMENT_PATH); |  */ | ||||||
|  |  | ||||||
| require('../entities/entity_constructor'); | require('../entities/entity_constructor'); | ||||||
| const optionService = require('../services/options'); |  | ||||||
| const sqlInit = require('../services/sql_init'); | const sqlInit = require('../services/sql_init'); | ||||||
| const myScryptService = require('../services/my_scrypt'); |  | ||||||
| const passwordEncryptionService = require('../services/password_encryption'); |  | ||||||
| const utils = require('../services/utils'); |  | ||||||
| const noteService = require('../services/notes'); | const noteService = require('../services/notes'); | ||||||
|  | const attributeService = require('../services/attributes'); | ||||||
| const cls = require('../services/cls'); | const cls = require('../services/cls'); | ||||||
| const cloningService = require('../services/cloning'); | const cloningService = require('../services/cloning'); | ||||||
| const loremIpsum = require('lorem-ipsum'); | const loremIpsum = require('lorem-ipsum').loremIpsum; | ||||||
|  |  | ||||||
| async function setUserNamePassword() { |  | ||||||
|     const username = "test"; |  | ||||||
|     const password = "test"; |  | ||||||
|  |  | ||||||
|     await optionService.setOption('username', username); |  | ||||||
|  |  | ||||||
|     await optionService.setOption('passwordVerificationSalt', utils.randomSecureToken(32)); |  | ||||||
|     await optionService.setOption('passwordDerivedKeySalt', utils.randomSecureToken(32)); |  | ||||||
|  |  | ||||||
|     const passwordVerificationKey = utils.toBase64(await myScryptService.getVerificationHash(password)); |  | ||||||
|     await optionService.setOption('passwordVerificationHash', passwordVerificationKey); |  | ||||||
|  |  | ||||||
|     await passwordEncryptionService.setDataKey(password, utils.randomSecureToken(16)); |  | ||||||
|  |  | ||||||
|     await sqlInit.initDbConnection(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const noteCount = parseInt(process.argv[2]); | const noteCount = parseInt(process.argv[2]); | ||||||
|  |  | ||||||
|  | if (!noteCount) { | ||||||
|  |     console.error(`Please enter number of notes as program parameter.`); | ||||||
|  |     process.exit(1); | ||||||
|  | } | ||||||
|  |  | ||||||
| const notes = ['root']; | const notes = ['root']; | ||||||
|  |  | ||||||
| function getRandomParentNoteId() { | function getRandomNoteId() { | ||||||
|     const index = Math.floor(Math.random() * notes.length); |     const index = Math.floor(Math.random() * notes.length); | ||||||
|  |  | ||||||
|     return notes[index]; |     return notes[index]; | ||||||
| } | } | ||||||
|  |  | ||||||
| async function start() { | async function start() { | ||||||
|     await setUserNamePassword(); |  | ||||||
|  |  | ||||||
|     for (let i = 0; i < noteCount; i++) { |     for (let i = 0; i < noteCount; i++) { | ||||||
|         const title = loremIpsum({ count: 1, units: 'sentences', sentenceLowerBound: 1, sentenceUpperBound: 10 }); |         const title = loremIpsum({ count: 1, units: 'sentences', sentenceLowerBound: 1, sentenceUpperBound: 10 }); | ||||||
|  |  | ||||||
| @@ -50,17 +34,17 @@ async function start() { | |||||||
|         const content = loremIpsum({ count: paragraphCount, units: 'paragraphs', sentenceLowerBound: 1, sentenceUpperBound: 15, |         const content = loremIpsum({ count: paragraphCount, units: 'paragraphs', sentenceLowerBound: 1, sentenceUpperBound: 15, | ||||||
|             paragraphLowerBound: 3, paragraphUpperBound: 10, format: 'html' }); |             paragraphLowerBound: 3, paragraphUpperBound: 10, format: 'html' }); | ||||||
|  |  | ||||||
|         const {note} = await noteService.createNote(getRandomParentNoteId(), title, content); |         const {note} = await noteService.createNote(getRandomNoteId(), title, content); | ||||||
|  |  | ||||||
|         console.log(`Created note ${i}: ${title}`); |         console.log(`Created note ${i}: ${title}`); | ||||||
|  |  | ||||||
|         notes.push(note.noteId); |         notes.push(note.noteId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // we'll create clones for 20% of notes |     // we'll create clones for 4% of notes | ||||||
|     for (let i = 0; i < (noteCount / 50); i++) { |     for (let i = 0; i < (noteCount / 25); i++) { | ||||||
|         const noteIdToClone = getRandomParentNoteId(); |         const noteIdToClone = getRandomNoteId(); | ||||||
|         const parentNoteId = getRandomParentNoteId(); |         const parentNoteId = getRandomNoteId(); | ||||||
|         const prefix = Math.random() > 0.8 ? "prefix" : null; |         const prefix = Math.random() > 0.8 ? "prefix" : null; | ||||||
|  |  | ||||||
|         const result = await cloningService.cloneNoteToParent(noteIdToClone, parentNoteId, prefix); |         const result = await cloningService.cloneNoteToParent(noteIdToClone, parentNoteId, prefix); | ||||||
| @@ -68,6 +52,30 @@ async function start() { | |||||||
|         console.log(`Cloning ${i}:`, result.success ? "succeeded" : "FAILED"); |         console.log(`Cloning ${i}:`, result.success ? "succeeded" : "FAILED"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     for (let i = 0; i < noteCount; i++) { | ||||||
|  |         await attributeService.createAttribute({ | ||||||
|  |             noteId: getRandomNoteId(), | ||||||
|  |             type: 'label', | ||||||
|  |             name: 'label', | ||||||
|  |             value: 'value', | ||||||
|  |             isInheritable: Math.random() > 0.1 // 10% are inheritable | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         console.log(`Creating label ${i}`); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     for (let i = 0; i < noteCount; i++) { | ||||||
|  |         await attributeService.createAttribute({ | ||||||
|  |             noteId: getRandomNoteId(), | ||||||
|  |             type: 'relation', | ||||||
|  |             name: 'relation', | ||||||
|  |             value: getRandomNoteId(), | ||||||
|  |             isInheritable: Math.random() > 0.1 // 10% are inheritable | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         console.log(`Creating relation ${i}`); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     process.exit(0); |     process.exit(0); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
| <html lang="en"> | <html lang="en"> | ||||||
| <head> | <head> | ||||||
|     <meta charset="utf-8"> |     <meta charset="utf-8"> | ||||||
|  |     <link rel="shortcut icon" href="favicon.ico"> | ||||||
|     <title>Trilium Notes</title> |     <title>Trilium Notes</title> | ||||||
| </head> | </head> | ||||||
| <body class="desktop theme-<%= theme %>" style="--main-font-size: <%= mainFontSize %>%; --tree-font-size: <%= treeFontSize %>%; --detail-font-size: <%= detailFontSize %>%;"> | <body class="desktop theme-<%= theme %>" style="--main-font-size: <%= mainFontSize %>%; --tree-font-size: <%= treeFontSize %>%; --detail-font-size: <%= detailFontSize %>%;"> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user