mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	DB dump tool feature complete
This commit is contained in:
		| @@ -17,6 +17,18 @@ npm install | |||||||
| See output of `node dump-db.js --help`: | See output of `node dump-db.js --help`: | ||||||
|  |  | ||||||
| ``` | ``` | ||||||
| Trilium Notes DB dump tool. Usage: | dump-db.js <path_to_document> <target_directory> | ||||||
| node dump-db.js PATH_TO_DOCUMENT_DB TARGET_PATH |  | ||||||
|  | dump the contents of document.db into the target directory | ||||||
|  |  | ||||||
|  | Positionals: | ||||||
|  | path_to_document  path to the document.db | ||||||
|  | target_directory  path of the directory into which the notes should be dumped | ||||||
|  |  | ||||||
|  | Options: | ||||||
|  | --help             Show help                                         [boolean] | ||||||
|  | --version          Show version number                               [boolean] | ||||||
|  | --password         Set password to be able to decrypt protected notes.[string] | ||||||
|  | --include-deleted  If set to true, dump also deleted notes. | ||||||
|  | [boolean] [default: false] | ||||||
| ``` | ``` | ||||||
|   | |||||||
| @@ -1,132 +1,33 @@ | |||||||
| #!/usr/bin/env node | #!/usr/bin/env node | ||||||
|  |  | ||||||
| const fs = require('fs'); | const yargs = require('yargs/yargs') | ||||||
| const sql = require("./inc/sql"); | const { hideBin } = require('yargs/helpers') | ||||||
|  | const dumpService = require("./inc/dump.js"); | ||||||
| const args = process.argv.slice(2); |  | ||||||
| const sanitize = require('sanitize-filename'); |  | ||||||
| const path = require("path"); |  | ||||||
| const mimeTypes = require("mime-types"); |  | ||||||
|  |  | ||||||
| if (args[0] === '-h' || args[0] === '--help') { |  | ||||||
|     printHelp(); |  | ||||||
|     process.exit(0); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if (args.length !== 2) { |  | ||||||
|     console.error(`Exactly 2 arguments are expected. Run with --help to see usage.`); |  | ||||||
|     process.exit(1); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const [documentPath, targetPath] = args; |  | ||||||
|  |  | ||||||
| if (!fs.existsSync(documentPath)) { |  | ||||||
|     console.error(`Path to document '${documentPath}' has not been found. Run with --help to see usage.`); |  | ||||||
|     process.exit(1); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if (!fs.existsSync(targetPath)) { |  | ||||||
|     const ret = fs.mkdirSync(targetPath, { recursive: true }); |  | ||||||
|  |  | ||||||
|     if (!ret) { |  | ||||||
|         console.error(`Target path '${targetPath}' could not be created. Run with --help to see usage.`); |  | ||||||
|         process.exit(1); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| sql.openDatabase(documentPath); |  | ||||||
|  |  | ||||||
| const existingPaths = {}; |  | ||||||
|  |  | ||||||
| dumpNote(targetPath, 'root'); |  | ||||||
|  |  | ||||||
| function getFileName(note, childTargetPath, safeTitle) { |  | ||||||
|     let existingExtension = path.extname(safeTitle).toLowerCase(); |  | ||||||
|     let newExtension; |  | ||||||
|  |  | ||||||
|     if (note.type === 'text') { |  | ||||||
|         newExtension = 'html'; |  | ||||||
|     } else if (note.mime === 'application/x-javascript' || note.mime === 'text/javascript') { |  | ||||||
|         newExtension = 'js'; |  | ||||||
|     } else if (existingExtension.length > 0) { // if the page already has an extension, then we'll just keep it |  | ||||||
|         newExtension = null; |  | ||||||
|     } else { |  | ||||||
|         if (note.mime?.toLowerCase()?.trim() === "image/jpg") { // image/jpg is invalid but pretty common |  | ||||||
|             newExtension = 'jpg'; |  | ||||||
|         } else { |  | ||||||
|             newExtension = mimeTypes.extension(note.mime) || "dat"; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     let fileNameWithPath = childTargetPath; |  | ||||||
|  |  | ||||||
|     // if the note is already named with extension (e.g. "jquery"), then it's silly to append exact same extension again |  | ||||||
|     if (newExtension && existingExtension !== "." + newExtension.toLowerCase()) { |  | ||||||
|         fileNameWithPath += "." + newExtension; |  | ||||||
|     } |  | ||||||
|     return fileNameWithPath; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function dumpNote(targetPath, noteId) { |  | ||||||
|     console.log(`Dumping note ${noteId}`); |  | ||||||
|  |  | ||||||
|     const note = sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]); |  | ||||||
|  |  | ||||||
|     let safeTitle = sanitize(note.title); |  | ||||||
|  |  | ||||||
|     if (safeTitle.length > 20) { |  | ||||||
|         safeTitle = safeTitle.substring(0, 20); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     let childTargetPath = targetPath + '/' + safeTitle; |  | ||||||
|  |  | ||||||
|     for (let i = 1; i < 100000 && childTargetPath in existingPaths; i++) { |  | ||||||
|         childTargetPath = targetPath + '/' + safeTitle + '_' + i; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     existingPaths[childTargetPath] = true; |  | ||||||
|  |  | ||||||
|  | yargs(hideBin(process.argv)) | ||||||
|  |     .command('$0 <path_to_document> <target_directory>', 'dump the contents of document.db into the target directory', (yargs) => { | ||||||
|  |         return yargs | ||||||
|  |             .positional('path_to_document', { describe: 'path to the document.db' }) | ||||||
|  |             .positional('target_directory', { describe: 'path of the directory into which the notes should be dumped' }) | ||||||
|  |     }, (argv) => { | ||||||
|         try { |         try { | ||||||
|         const {content} = sql.getRow("SELECT content FROM note_contents WHERE noteId = ?", [noteId]); |             dumpService.dumpDocument(argv.path_to_document, argv.target_directory, { | ||||||
|  |                 includeDeleted: argv.includeDeleted, | ||||||
|         if (!isContentEmpty(content)) { |                 password: argv.password | ||||||
|             const fileNameWithPath = getFileName(note, childTargetPath, safeTitle); |             }); | ||||||
|  |  | ||||||
|             fs.writeFileSync(fileNameWithPath, content); |  | ||||||
|         } |  | ||||||
|         } |         } | ||||||
|         catch (e) { |         catch (e) { | ||||||
|         console.log(`Writing ${note.noteId} failed with error ${e.message}`); |             console.error(`Unrecoverable error:`, e); | ||||||
|  |             process.exit(1); | ||||||
|         } |         } | ||||||
|  |     }) | ||||||
|     const childNoteIds = sql.getColumn("SELECT noteId FROM branches WHERE parentNoteId = ?", [noteId]); |     .option('password', { | ||||||
|  |         type: 'string', | ||||||
|     if (childNoteIds.length > 0) { |         description: 'Set password to be able to decrypt protected notes.' | ||||||
|         fs.mkdirSync(childTargetPath, { recursive: true }); |     }) | ||||||
|  |     .option('include-deleted', { | ||||||
|         for (const childNoteId of childNoteIds) { |         type: 'boolean', | ||||||
|             dumpNote(childTargetPath, childNoteId); |         default: false, | ||||||
|         } |         description: 'If set to true, dump also deleted notes.' | ||||||
|     } |     }) | ||||||
| } |     .parse(); | ||||||
|  |  | ||||||
| function isContentEmpty(content) { |  | ||||||
|     if (!content) { |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (typeof content === "string") { |  | ||||||
|         return !content.trim() || content.trim() === '<p></p>'; |  | ||||||
|     } |  | ||||||
|     else if (Buffer.isBuffer(content)) { |  | ||||||
|         return content.length === 0; |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function printHelp() { |  | ||||||
|     console.log(`Trilium Notes DB dump tool. Usage: |  | ||||||
| node dump-db.js PATH_TO_DOCUMENT_DB TARGET_PATH`); |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -1,14 +1,24 @@ | |||||||
| import crypto from "crypto"; | const crypto = require("crypto"); | ||||||
| import sql from "./sql.js"; | const sql = require("./sql.js"); | ||||||
|  | const decryptService = require("./decrypt.js"); | ||||||
|  |  | ||||||
| function getDataKey(password) { | function getDataKey(password) { | ||||||
|  |     if (!password) { | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     try { | ||||||
|         const passwordDerivedKey = getPasswordDerivedKey(password); |         const passwordDerivedKey = getPasswordDerivedKey(password); | ||||||
|  |  | ||||||
|         const encryptedDataKey = getOption('encryptedDataKey'); |         const encryptedDataKey = getOption('encryptedDataKey'); | ||||||
|  |  | ||||||
|     const decryptedDataKey = decrypt(passwordDerivedKey, encryptedDataKey, 16); |         const decryptedDataKey = decryptService.decrypt(passwordDerivedKey, encryptedDataKey, 16); | ||||||
|  |  | ||||||
|         return decryptedDataKey; |         return decryptedDataKey; | ||||||
|  |     } | ||||||
|  |     catch (e) { | ||||||
|  |         throw new Error(`Cannot read data key, the entered password might be wrong. The underlying error: '${e.message}', stack:\n${e.stack}`); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function getPasswordDerivedKey(password) { | function getPasswordDerivedKey(password) { | ||||||
| @@ -25,7 +35,7 @@ function getScryptHash(password, salt) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function getOption(name) { | function getOption(name) { | ||||||
|     return sql.getValue("SELECT value FROM options WHERE name = ?", name); |     return sql.getValue("SELECT value FROM options WHERE name = ?", [name]); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import crypto from "crypto"; | const crypto = require("crypto"); | ||||||
|  |  | ||||||
| function decryptString(dataKey, cipherText) { | function decryptString(dataKey, cipherText) { | ||||||
|     const buffer = decrypt(dataKey, cipherText); |     const buffer = decrypt(dataKey, cipherText); | ||||||
| @@ -59,6 +59,19 @@ function decrypt(key, cipherText, ivLength = 13) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function pad(data) { | ||||||
|  |     if (data.length > 16) { | ||||||
|  |         data = data.slice(0, 16); | ||||||
|  |     } | ||||||
|  |     else if (data.length < 16) { | ||||||
|  |         const zeros = Array(16 - data.length).fill(0); | ||||||
|  |  | ||||||
|  |         data = Buffer.concat([data, Buffer.from(zeros)]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return Buffer.from(data); | ||||||
|  | } | ||||||
|  |  | ||||||
| function arraysIdentical(a, b) { | function arraysIdentical(a, b) { | ||||||
|     let i = a.length; |     let i = a.length; | ||||||
|     if (i !== b.length) return false; |     if (i !== b.length) return false; | ||||||
|   | |||||||
							
								
								
									
										171
									
								
								dump-db/inc/dump.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								dump-db/inc/dump.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,171 @@ | |||||||
|  | const fs = require("fs"); | ||||||
|  | const sanitize = require("sanitize-filename"); | ||||||
|  | const sql = require("./sql.js"); | ||||||
|  | const decryptService = require("./decrypt.js"); | ||||||
|  | const dataKeyService = require("./data_key.js"); | ||||||
|  | const extensionService = require("./extension.js"); | ||||||
|  |  | ||||||
|  | function dumpDocument(documentPath, targetPath, options) { | ||||||
|  |     const stats = { | ||||||
|  |         succeeded: 0, | ||||||
|  |         failed: 0, | ||||||
|  |         protected: 0, | ||||||
|  |         deleted: 0 | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     validatePaths(documentPath, targetPath); | ||||||
|  |  | ||||||
|  |     sql.openDatabase(documentPath); | ||||||
|  |  | ||||||
|  |     const dataKey = dataKeyService.getDataKey(options.password); | ||||||
|  |  | ||||||
|  |     const existingPaths = {}; | ||||||
|  |     const noteIdToPath = {}; | ||||||
|  |  | ||||||
|  |     dumpNote(targetPath, 'root'); | ||||||
|  |  | ||||||
|  |     printDumpResults(stats, options); | ||||||
|  |  | ||||||
|  |     function dumpNote(targetPath, noteId) { | ||||||
|  |         console.log(`Reading note '${noteId}'`); | ||||||
|  |  | ||||||
|  |         let childTargetPath, note, fileNameWithPath; | ||||||
|  |  | ||||||
|  |         try { | ||||||
|  |             note = sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]); | ||||||
|  |  | ||||||
|  |             if (note.isDeleted) { | ||||||
|  |                 stats.deleted++; | ||||||
|  |  | ||||||
|  |                 if (!options.includeDeleted) { | ||||||
|  |                     console.log(`Note '${noteId}' is deleted and --include-deleted option is not used, skipping.`); | ||||||
|  |  | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (note.isProtected) { | ||||||
|  |                 stats.protected++; | ||||||
|  |  | ||||||
|  |                 note.title = decryptService.decryptString(dataKey, note.title); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             let safeTitle = sanitize(note.title); | ||||||
|  |  | ||||||
|  |             if (safeTitle.length > 20) { | ||||||
|  |                 safeTitle = safeTitle.substring(0, 20); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             childTargetPath = targetPath + '/' + safeTitle; | ||||||
|  |  | ||||||
|  |             for (let i = 1; i < 100000 && childTargetPath in existingPaths; i++) { | ||||||
|  |                 childTargetPath = targetPath + '/' + safeTitle + '_' + i; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             existingPaths[childTargetPath] = true; | ||||||
|  |  | ||||||
|  |             if (note.noteId in noteIdToPath) { | ||||||
|  |                 const message = `Note '${noteId}' has been already dumped to ${noteIdToPath[note.noteId]}`; | ||||||
|  |  | ||||||
|  |                 console.log(message); | ||||||
|  |  | ||||||
|  |                 fs.writeFileSync(childTargetPath, message); | ||||||
|  |  | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             let {content} = sql.getRow("SELECT content FROM note_contents WHERE noteId = ?", [noteId]); | ||||||
|  |  | ||||||
|  |             if (content !== null && note.isProtected && dataKey) { | ||||||
|  |                 content = decryptService.decrypt(dataKey, content); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (isContentEmpty(content)) { | ||||||
|  |                 console.log(`Note '${noteId}' is empty, skipping.`); | ||||||
|  |             } else { | ||||||
|  |                 fileNameWithPath = extensionService.getFileName(note, childTargetPath, safeTitle); | ||||||
|  |  | ||||||
|  |                 fs.writeFileSync(fileNameWithPath, content); | ||||||
|  |  | ||||||
|  |                 stats.succeeded++; | ||||||
|  |  | ||||||
|  |                 console.log(`Dumped note '${noteId}' into ${fileNameWithPath} successfully.`); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             noteIdToPath[noteId] = childTargetPath; | ||||||
|  |         } | ||||||
|  |         catch (e) { | ||||||
|  |             console.error(`DUMPERROR: Writing '${noteId}' failed with error '${e.message}':\n${e.stack}`); | ||||||
|  |  | ||||||
|  |             stats.failed++; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         const childNoteIds = sql.getColumn("SELECT noteId FROM branches WHERE parentNoteId = ?", [noteId]); | ||||||
|  |  | ||||||
|  |         if (childNoteIds.length > 0) { | ||||||
|  |             if (childTargetPath === fileNameWithPath) { | ||||||
|  |                 childTargetPath += '_dir'; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             try { | ||||||
|  |                 fs.mkdirSync(childTargetPath, {recursive: true}); | ||||||
|  |             } | ||||||
|  |             catch (e) { | ||||||
|  |                 console.error(`DUMPERROR: Creating directory ${childTargetPath} failed with error '${e.message}'`); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             for (const childNoteId of childNoteIds) { | ||||||
|  |                 dumpNote(childTargetPath, childNoteId); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function printDumpResults(stats, options) { | ||||||
|  |     console.log('\n----------------------- STATS -----------------------'); | ||||||
|  |     console.log('Successfully dumpted notes:   ', stats.succeeded.toString().padStart(5, ' ')); | ||||||
|  |     console.log('Protected notes:              ', stats.protected.toString().padStart(5, ' '), options.password ? '' : '(skipped)'); | ||||||
|  |     console.log('Failed notes:                 ', stats.failed.toString().padStart(5, ' ')); | ||||||
|  |     console.log('Deleted notes:                ', stats.deleted.toString().padStart(5, ' '), options.includeDeleted ? "(dumped)" : "(at least, skipped)"); | ||||||
|  |     console.log('-----------------------------------------------------'); | ||||||
|  |  | ||||||
|  |     if (!options.password && stats.protected > 0) { | ||||||
|  |         console.log("\nWARNING: protected notes are present in the document but no password has been provided. Protected notes have not been dumped."); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function isContentEmpty(content) { | ||||||
|  |     if (!content) { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (typeof content === "string") { | ||||||
|  |         return !content.trim() || content.trim() === '<p></p>'; | ||||||
|  |     } | ||||||
|  |     else if (Buffer.isBuffer(content)) { | ||||||
|  |         return content.length === 0; | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function validatePaths(documentPath, targetPath) { | ||||||
|  |     if (!fs.existsSync(documentPath)) { | ||||||
|  |         console.error(`Path to document '${documentPath}' has not been found. Run with --help to see usage.`); | ||||||
|  |         process.exit(1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (!fs.existsSync(targetPath)) { | ||||||
|  |         const ret = fs.mkdirSync(targetPath, {recursive: true}); | ||||||
|  |  | ||||||
|  |         if (!ret) { | ||||||
|  |             console.error(`Target path '${targetPath}' could not be created. Run with --help to see usage.`); | ||||||
|  |             process.exit(1); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = { | ||||||
|  |     dumpDocument | ||||||
|  | }; | ||||||
							
								
								
									
										34
									
								
								dump-db/inc/extension.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								dump-db/inc/extension.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | const path = require("path"); | ||||||
|  | const mimeTypes = require("mime-types"); | ||||||
|  |  | ||||||
|  | function getFileName(note, childTargetPath, safeTitle) { | ||||||
|  |     let existingExtension = path.extname(safeTitle).toLowerCase(); | ||||||
|  |     let newExtension; | ||||||
|  |  | ||||||
|  |     if (note.type === 'text') { | ||||||
|  |         newExtension = 'html'; | ||||||
|  |     } else if (note.mime === 'application/x-javascript' || note.mime === 'text/javascript') { | ||||||
|  |         newExtension = 'js'; | ||||||
|  |     } else if (existingExtension.length > 0) { // if the page already has an extension, then we'll just keep it | ||||||
|  |         newExtension = null; | ||||||
|  |     } else { | ||||||
|  |         if (note.mime?.toLowerCase()?.trim() === "image/jpg") { // image/jpg is invalid but pretty common | ||||||
|  |             newExtension = 'jpg'; | ||||||
|  |         } else { | ||||||
|  |             newExtension = mimeTypes.extension(note.mime) || "dat"; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     let fileNameWithPath = childTargetPath; | ||||||
|  |  | ||||||
|  |     // if the note is already named with extension (e.g. "jquery"), then it's silly to append exact same extension again | ||||||
|  |     if (newExtension && existingExtension !== "." + newExtension.toLowerCase()) { | ||||||
|  |         fileNameWithPath += "." + newExtension; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return fileNameWithPath; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = { | ||||||
|  |     getFileName | ||||||
|  | }; | ||||||
							
								
								
									
										418
									
								
								dump-db/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										418
									
								
								dump-db/package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -10,8 +10,9 @@ | |||||||
|       "license": "ISC", |       "license": "ISC", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "better-sqlite3": "7.5.0", |         "better-sqlite3": "7.5.0", | ||||||
|         "mime-types": "^2.1.34", |         "mime-types": "2.1.34", | ||||||
|         "sanitize-filename": "1.6.3" |         "sanitize-filename": "1.6.3", | ||||||
|  |         "yargs": "17.3.1" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/ansi-regex": { |     "node_modules/ansi-regex": { | ||||||
| @@ -124,6 +125,56 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", |       "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", | ||||||
|       "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" |       "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/cliui": { | ||||||
|  |       "version": "7.0.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", | ||||||
|  |       "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "string-width": "^4.2.0", | ||||||
|  |         "strip-ansi": "^6.0.0", | ||||||
|  |         "wrap-ansi": "^7.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/cliui/node_modules/ansi-regex": { | ||||||
|  |       "version": "5.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", | ||||||
|  |       "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/cliui/node_modules/is-fullwidth-code-point": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/cliui/node_modules/string-width": { | ||||||
|  |       "version": "4.2.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", | ||||||
|  |       "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "emoji-regex": "^8.0.0", | ||||||
|  |         "is-fullwidth-code-point": "^3.0.0", | ||||||
|  |         "strip-ansi": "^6.0.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/cliui/node_modules/strip-ansi": { | ||||||
|  |       "version": "6.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", | ||||||
|  |       "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "ansi-regex": "^5.0.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/code-point-at": { |     "node_modules/code-point-at": { | ||||||
|       "version": "1.1.0", |       "version": "1.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", |       "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", | ||||||
| @@ -177,6 +228,11 @@ | |||||||
|         "node": ">=8" |         "node": ">=8" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/emoji-regex": { | ||||||
|  |       "version": "8.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", | ||||||
|  |       "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" | ||||||
|  |     }, | ||||||
|     "node_modules/end-of-stream": { |     "node_modules/end-of-stream": { | ||||||
|       "version": "1.4.4", |       "version": "1.4.4", | ||||||
|       "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", |       "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", | ||||||
| @@ -185,6 +241,14 @@ | |||||||
|         "once": "^1.4.0" |         "once": "^1.4.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/escalade": { | ||||||
|  |       "version": "3.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", | ||||||
|  |       "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=6" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/expand-template": { |     "node_modules/expand-template": { | ||||||
|       "version": "2.0.3", |       "version": "2.0.3", | ||||||
|       "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", |       "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", | ||||||
| @@ -218,6 +282,14 @@ | |||||||
|         "wide-align": "^1.1.0" |         "wide-align": "^1.1.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/get-caller-file": { | ||||||
|  |       "version": "2.0.5", | ||||||
|  |       "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", | ||||||
|  |       "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": "6.* || 8.* || >= 10.*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/github-from-package": { |     "node_modules/github-from-package": { | ||||||
|       "version": "0.0.0", |       "version": "0.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", |       "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", | ||||||
| @@ -443,6 +515,14 @@ | |||||||
|         "util-deprecate": "~1.0.1" |         "util-deprecate": "~1.0.1" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/require-directory": { | ||||||
|  |       "version": "2.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", | ||||||
|  |       "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=0.10.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/safe-buffer": { |     "node_modules/safe-buffer": { | ||||||
|       "version": "5.1.2", |       "version": "5.1.2", | ||||||
|       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", |       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", | ||||||
| @@ -639,15 +719,174 @@ | |||||||
|         "string-width": "^1.0.2 || 2 || 3 || 4" |         "string-width": "^1.0.2 || 2 || 3 || 4" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/wrap-ansi": { | ||||||
|  |       "version": "7.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", | ||||||
|  |       "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "ansi-styles": "^4.0.0", | ||||||
|  |         "string-width": "^4.1.0", | ||||||
|  |         "strip-ansi": "^6.0.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=10" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "url": "https://github.com/chalk/wrap-ansi?sponsor=1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/wrap-ansi/node_modules/ansi-regex": { | ||||||
|  |       "version": "5.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", | ||||||
|  |       "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/wrap-ansi/node_modules/ansi-styles": { | ||||||
|  |       "version": "4.3.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", | ||||||
|  |       "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "color-convert": "^2.0.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "url": "https://github.com/chalk/ansi-styles?sponsor=1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/wrap-ansi/node_modules/color-convert": { | ||||||
|  |       "version": "2.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", | ||||||
|  |       "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "color-name": "~1.1.4" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=7.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/wrap-ansi/node_modules/color-name": { | ||||||
|  |       "version": "1.1.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", | ||||||
|  |       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/wrap-ansi/node_modules/string-width": { | ||||||
|  |       "version": "4.2.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", | ||||||
|  |       "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "emoji-regex": "^8.0.0", | ||||||
|  |         "is-fullwidth-code-point": "^3.0.0", | ||||||
|  |         "strip-ansi": "^6.0.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/wrap-ansi/node_modules/strip-ansi": { | ||||||
|  |       "version": "6.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", | ||||||
|  |       "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "ansi-regex": "^5.0.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/wrappy": { |     "node_modules/wrappy": { | ||||||
|       "version": "1.0.2", |       "version": "1.0.2", | ||||||
|       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", |       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", | ||||||
|       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" |       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/y18n": { | ||||||
|  |       "version": "5.0.8", | ||||||
|  |       "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", | ||||||
|  |       "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=10" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/yallist": { |     "node_modules/yallist": { | ||||||
|       "version": "4.0.0", |       "version": "4.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", |       "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", | ||||||
|       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" |       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/yargs": { | ||||||
|  |       "version": "17.3.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", | ||||||
|  |       "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "cliui": "^7.0.2", | ||||||
|  |         "escalade": "^3.1.1", | ||||||
|  |         "get-caller-file": "^2.0.5", | ||||||
|  |         "require-directory": "^2.1.1", | ||||||
|  |         "string-width": "^4.2.3", | ||||||
|  |         "y18n": "^5.0.5", | ||||||
|  |         "yargs-parser": "^21.0.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/yargs-parser": { | ||||||
|  |       "version": "21.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz", | ||||||
|  |       "integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/yargs/node_modules/ansi-regex": { | ||||||
|  |       "version": "5.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", | ||||||
|  |       "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/yargs/node_modules/is-fullwidth-code-point": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/yargs/node_modules/string-width": { | ||||||
|  |       "version": "4.2.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", | ||||||
|  |       "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "emoji-regex": "^8.0.0", | ||||||
|  |         "is-fullwidth-code-point": "^3.0.0", | ||||||
|  |         "strip-ansi": "^6.0.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/yargs/node_modules/strip-ansi": { | ||||||
|  |       "version": "6.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", | ||||||
|  |       "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "ansi-regex": "^5.0.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
| @@ -728,6 +967,46 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", |       "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", | ||||||
|       "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" |       "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" | ||||||
|     }, |     }, | ||||||
|  |     "cliui": { | ||||||
|  |       "version": "7.0.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", | ||||||
|  |       "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", | ||||||
|  |       "requires": { | ||||||
|  |         "string-width": "^4.2.0", | ||||||
|  |         "strip-ansi": "^6.0.0", | ||||||
|  |         "wrap-ansi": "^7.0.0" | ||||||
|  |       }, | ||||||
|  |       "dependencies": { | ||||||
|  |         "ansi-regex": { | ||||||
|  |           "version": "5.0.1", | ||||||
|  |           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", | ||||||
|  |           "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" | ||||||
|  |         }, | ||||||
|  |         "is-fullwidth-code-point": { | ||||||
|  |           "version": "3.0.0", | ||||||
|  |           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", | ||||||
|  |           "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" | ||||||
|  |         }, | ||||||
|  |         "string-width": { | ||||||
|  |           "version": "4.2.3", | ||||||
|  |           "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", | ||||||
|  |           "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", | ||||||
|  |           "requires": { | ||||||
|  |             "emoji-regex": "^8.0.0", | ||||||
|  |             "is-fullwidth-code-point": "^3.0.0", | ||||||
|  |             "strip-ansi": "^6.0.1" | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         "strip-ansi": { | ||||||
|  |           "version": "6.0.1", | ||||||
|  |           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", | ||||||
|  |           "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", | ||||||
|  |           "requires": { | ||||||
|  |             "ansi-regex": "^5.0.1" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "code-point-at": { |     "code-point-at": { | ||||||
|       "version": "1.1.0", |       "version": "1.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", |       "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", | ||||||
| @@ -766,6 +1045,11 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.0.tgz", |       "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.0.tgz", | ||||||
|       "integrity": "sha512-S55LzUl8HUav8l9E2PBTlC5PAJrHK7tkM+XXFGD+fbsbkTzhCpG6K05LxJcUOEWzMa4v6ptcMZ9s3fOdJDu0Zw==" |       "integrity": "sha512-S55LzUl8HUav8l9E2PBTlC5PAJrHK7tkM+XXFGD+fbsbkTzhCpG6K05LxJcUOEWzMa4v6ptcMZ9s3fOdJDu0Zw==" | ||||||
|     }, |     }, | ||||||
|  |     "emoji-regex": { | ||||||
|  |       "version": "8.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", | ||||||
|  |       "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" | ||||||
|  |     }, | ||||||
|     "end-of-stream": { |     "end-of-stream": { | ||||||
|       "version": "1.4.4", |       "version": "1.4.4", | ||||||
|       "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", |       "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", | ||||||
| @@ -774,6 +1058,11 @@ | |||||||
|         "once": "^1.4.0" |         "once": "^1.4.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "escalade": { | ||||||
|  |       "version": "3.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", | ||||||
|  |       "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" | ||||||
|  |     }, | ||||||
|     "expand-template": { |     "expand-template": { | ||||||
|       "version": "2.0.3", |       "version": "2.0.3", | ||||||
|       "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", |       "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", | ||||||
| @@ -804,6 +1093,11 @@ | |||||||
|         "wide-align": "^1.1.0" |         "wide-align": "^1.1.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "get-caller-file": { | ||||||
|  |       "version": "2.0.5", | ||||||
|  |       "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", | ||||||
|  |       "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" | ||||||
|  |     }, | ||||||
|     "github-from-package": { |     "github-from-package": { | ||||||
|       "version": "0.0.0", |       "version": "0.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", |       "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", | ||||||
| @@ -979,6 +1273,11 @@ | |||||||
|         "util-deprecate": "~1.0.1" |         "util-deprecate": "~1.0.1" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "require-directory": { | ||||||
|  |       "version": "2.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", | ||||||
|  |       "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" | ||||||
|  |     }, | ||||||
|     "safe-buffer": { |     "safe-buffer": { | ||||||
|       "version": "5.1.2", |       "version": "5.1.2", | ||||||
|       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", |       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", | ||||||
| @@ -1125,15 +1424,130 @@ | |||||||
|         "string-width": "^1.0.2 || 2 || 3 || 4" |         "string-width": "^1.0.2 || 2 || 3 || 4" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "wrap-ansi": { | ||||||
|  |       "version": "7.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", | ||||||
|  |       "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", | ||||||
|  |       "requires": { | ||||||
|  |         "ansi-styles": "^4.0.0", | ||||||
|  |         "string-width": "^4.1.0", | ||||||
|  |         "strip-ansi": "^6.0.0" | ||||||
|  |       }, | ||||||
|  |       "dependencies": { | ||||||
|  |         "ansi-regex": { | ||||||
|  |           "version": "5.0.1", | ||||||
|  |           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", | ||||||
|  |           "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" | ||||||
|  |         }, | ||||||
|  |         "ansi-styles": { | ||||||
|  |           "version": "4.3.0", | ||||||
|  |           "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", | ||||||
|  |           "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", | ||||||
|  |           "requires": { | ||||||
|  |             "color-convert": "^2.0.1" | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         "color-convert": { | ||||||
|  |           "version": "2.0.1", | ||||||
|  |           "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", | ||||||
|  |           "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", | ||||||
|  |           "requires": { | ||||||
|  |             "color-name": "~1.1.4" | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         "color-name": { | ||||||
|  |           "version": "1.1.4", | ||||||
|  |           "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", | ||||||
|  |           "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" | ||||||
|  |         }, | ||||||
|  |         "is-fullwidth-code-point": { | ||||||
|  |           "version": "3.0.0", | ||||||
|  |           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", | ||||||
|  |           "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" | ||||||
|  |         }, | ||||||
|  |         "string-width": { | ||||||
|  |           "version": "4.2.3", | ||||||
|  |           "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", | ||||||
|  |           "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", | ||||||
|  |           "requires": { | ||||||
|  |             "emoji-regex": "^8.0.0", | ||||||
|  |             "is-fullwidth-code-point": "^3.0.0", | ||||||
|  |             "strip-ansi": "^6.0.1" | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         "strip-ansi": { | ||||||
|  |           "version": "6.0.1", | ||||||
|  |           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", | ||||||
|  |           "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", | ||||||
|  |           "requires": { | ||||||
|  |             "ansi-regex": "^5.0.1" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "wrappy": { |     "wrappy": { | ||||||
|       "version": "1.0.2", |       "version": "1.0.2", | ||||||
|       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", |       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", | ||||||
|       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" |       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" | ||||||
|     }, |     }, | ||||||
|  |     "y18n": { | ||||||
|  |       "version": "5.0.8", | ||||||
|  |       "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", | ||||||
|  |       "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" | ||||||
|  |     }, | ||||||
|     "yallist": { |     "yallist": { | ||||||
|       "version": "4.0.0", |       "version": "4.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", |       "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", | ||||||
|       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" |       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" | ||||||
|  |     }, | ||||||
|  |     "yargs": { | ||||||
|  |       "version": "17.3.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", | ||||||
|  |       "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", | ||||||
|  |       "requires": { | ||||||
|  |         "cliui": "^7.0.2", | ||||||
|  |         "escalade": "^3.1.1", | ||||||
|  |         "get-caller-file": "^2.0.5", | ||||||
|  |         "require-directory": "^2.1.1", | ||||||
|  |         "string-width": "^4.2.3", | ||||||
|  |         "y18n": "^5.0.5", | ||||||
|  |         "yargs-parser": "^21.0.0" | ||||||
|  |       }, | ||||||
|  |       "dependencies": { | ||||||
|  |         "ansi-regex": { | ||||||
|  |           "version": "5.0.1", | ||||||
|  |           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", | ||||||
|  |           "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" | ||||||
|  |         }, | ||||||
|  |         "is-fullwidth-code-point": { | ||||||
|  |           "version": "3.0.0", | ||||||
|  |           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", | ||||||
|  |           "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" | ||||||
|  |         }, | ||||||
|  |         "string-width": { | ||||||
|  |           "version": "4.2.3", | ||||||
|  |           "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", | ||||||
|  |           "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", | ||||||
|  |           "requires": { | ||||||
|  |             "emoji-regex": "^8.0.0", | ||||||
|  |             "is-fullwidth-code-point": "^3.0.0", | ||||||
|  |             "strip-ansi": "^6.0.1" | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         "strip-ansi": { | ||||||
|  |           "version": "6.0.1", | ||||||
|  |           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", | ||||||
|  |           "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", | ||||||
|  |           "requires": { | ||||||
|  |             "ansi-regex": "^5.0.1" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "yargs-parser": { | ||||||
|  |       "version": "21.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz", | ||||||
|  |       "integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==" | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "better-sqlite3": "7.5.0", |     "better-sqlite3": "7.5.0", | ||||||
|     "mime-types": "2.1.34", |     "mime-types": "2.1.34", | ||||||
|     "sanitize-filename": "1.6.3" |     "sanitize-filename": "1.6.3", | ||||||
|  |     "yargs": "17.3.1" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										913
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										913
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
									
									
									
									
								
							| @@ -42,7 +42,7 @@ | |||||||
|     "@electron/remote": "2.0.4", |     "@electron/remote": "2.0.4", | ||||||
|     "express": "4.17.2", |     "express": "4.17.2", | ||||||
|     "express-partial-content": "1.0.2", |     "express-partial-content": "1.0.2", | ||||||
|     "express-rate-limit": "6.2.0", |     "express-rate-limit": "6.2.1", | ||||||
|     "express-session": "1.17.2", |     "express-session": "1.17.2", | ||||||
|     "fs-extra": "10.0.0", |     "fs-extra": "10.0.0", | ||||||
|     "helmet": "5.0.2", |     "helmet": "5.0.2", | ||||||
| @@ -59,7 +59,7 @@ | |||||||
|     "jsdom": "19.0.0", |     "jsdom": "19.0.0", | ||||||
|     "mime-types": "2.1.34", |     "mime-types": "2.1.34", | ||||||
|     "multer": "1.4.4", |     "multer": "1.4.4", | ||||||
|     "node-abi": "3.7.0", |     "node-abi": "3.8.0", | ||||||
|     "normalize-strings": "1.1.1", |     "normalize-strings": "1.1.1", | ||||||
|     "open": "8.4.0", |     "open": "8.4.0", | ||||||
|     "portscanner": "2.2.0", |     "portscanner": "2.2.0", | ||||||
| @@ -67,7 +67,7 @@ | |||||||
|     "request": "2.88.2", |     "request": "2.88.2", | ||||||
|     "rimraf": "3.0.2", |     "rimraf": "3.0.2", | ||||||
|     "sanitize-filename": "1.6.3", |     "sanitize-filename": "1.6.3", | ||||||
|     "sanitize-html": "2.6.1", |     "sanitize-html": "2.7.0", | ||||||
|     "sax": "1.2.4", |     "sax": "1.2.4", | ||||||
|     "semver": "7.3.5", |     "semver": "7.3.5", | ||||||
|     "serve-favicon": "2.5.0", |     "serve-favicon": "2.5.0", | ||||||
| @@ -77,13 +77,13 @@ | |||||||
|     "tmp": "0.2.1", |     "tmp": "0.2.1", | ||||||
|     "turndown": "7.1.1", |     "turndown": "7.1.1", | ||||||
|     "unescape": "1.0.1", |     "unescape": "1.0.1", | ||||||
|     "ws": "8.4.2", |     "ws": "8.5.0", | ||||||
|     "yauzl": "2.10.0" |     "yauzl": "2.10.0" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "cross-env": "7.0.3", |     "cross-env": "7.0.3", | ||||||
|     "electron": "16.0.8", |     "electron": "16.0.8", | ||||||
|     "electron-builder": "22.14.5", |     "electron-builder": "22.14.13", | ||||||
|     "electron-packager": "15.4.0", |     "electron-packager": "15.4.0", | ||||||
|     "electron-rebuild": "3.2.7", |     "electron-rebuild": "3.2.7", | ||||||
|     "esm": "3.2.25", |     "esm": "3.2.25", | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user