diff --git a/src/routes/api/import.js b/src/routes/api/import.ts similarity index 65% rename from src/routes/api/import.js rename to src/routes/api/import.ts index 978fe9d7c..6062ae37f 100644 --- a/src/routes/api/import.js +++ b/src/routes/api/import.ts @@ -1,18 +1,20 @@ "use strict"; -const enexImportService = require('../../services/import/enex'); -const opmlImportService = require('../../services/import/opml'); -const zipImportService = require('../../services/import/zip'); -const singleImportService = require('../../services/import/single'); -const cls = require('../../services/cls'); -const path = require('path'); -const becca = require('../../becca/becca'); -const beccaLoader = require('../../becca/becca_loader'); -const log = require('../../services/log'); -const TaskContext = require('../../services/task_context'); -const ValidationError = require('../../errors/validation_error'); +import enexImportService = require('../../services/import/enex'); +import opmlImportService = require('../../services/import/opml'); +import zipImportService = require('../../services/import/zip'); +import singleImportService = require('../../services/import/single'); +import cls = require('../../services/cls'); +import path = require('path'); +import becca = require('../../becca/becca'); +import beccaLoader = require('../../becca/becca_loader'); +import log = require('../../services/log'); +import TaskContext = require('../../services/task_context'); +import ValidationError = require('../../errors/validation_error'); +import { Request } from 'express'; +import BNote = require('../../becca/entities/bnote'); -async function importNotesToBranch(req) { +async function importNotesToBranch(req: Request) { const { parentNoteId } = req.params; const { taskId, last } = req.body; @@ -25,7 +27,7 @@ async function importNotesToBranch(req) { replaceUnderscoresWithSpaces: req.body.replaceUnderscoresWithSpaces !== 'false' }; - const file = req.file; + const file = (req as any).file; if (!file) { throw new ValidationError("No file has been uploaded"); @@ -42,7 +44,7 @@ async function importNotesToBranch(req) { // eliminate flickering during import cls.ignoreEntityChangeIds(); - let note; // typically root of the import - client can show it after finishing the import + let note: BNote | null; // typically root of the import - client can show it after finishing the import const taskContext = TaskContext.getInstance(taskId, 'importNotes', options); @@ -50,14 +52,24 @@ async function importNotesToBranch(req) { if (extension === '.zip' && options.explodeArchives) { note = await zipImportService.importZip(taskContext, file.buffer, parentNote); } else if (extension === '.opml' && options.explodeArchives) { - note = await opmlImportService.importOpml(taskContext, file.buffer, parentNote); + const importResult = await opmlImportService.importOpml(taskContext, file.buffer, parentNote); + if (!Array.isArray(importResult)) { + note = importResult; + } else { + return importResult; + } } else if (extension === '.enex' && options.explodeArchives) { - note = await enexImportService.importEnex(taskContext, file, parentNote); + const importResult = await enexImportService.importEnex(taskContext, file, parentNote); + if (!Array.isArray(importResult)) { + note = importResult; + } else { + return importResult; + } } else { note = await singleImportService.importSingleFile(taskContext, file, parentNote); } } - catch (e) { + catch (e: any) { const message = `Import failed with following error: '${e.message}'. More details might be in the logs.`; taskContext.reportError(message); @@ -66,11 +78,15 @@ async function importNotesToBranch(req) { return [500, message]; } + if (!note) { + return [500, "No note was generated as a result of the import."]; + } + if (last === "true") { // small timeout to avoid race condition (the message is received before the transaction is committed) setTimeout(() => taskContext.taskSucceeded({ parentNoteId: parentNoteId, - importedNoteId: note.noteId + importedNoteId: note?.noteId }), 1000); } @@ -80,7 +96,7 @@ async function importNotesToBranch(req) { return note.getPojo(); } -async function importAttachmentsToNote(req) { +async function importAttachmentsToNote(req: Request) { const { parentNoteId } = req.params; const { taskId, last } = req.body; @@ -88,7 +104,7 @@ async function importAttachmentsToNote(req) { shrinkImages: req.body.shrinkImages !== 'false', }; - const file = req.file; + const file = (req as any).file; if (!file) { throw new ValidationError("No file has been uploaded"); @@ -102,7 +118,7 @@ async function importAttachmentsToNote(req) { try { await singleImportService.importAttachment(taskContext, file, parentNote); } - catch (e) { + catch (e: any) { const message = `Import failed with following error: '${e.message}'. More details might be in the logs.`; taskContext.reportError(message); @@ -119,7 +135,7 @@ async function importAttachmentsToNote(req) { } } -module.exports = { +export = { importNotesToBranch, importAttachmentsToNote }; diff --git a/src/routes/routes.js b/src/routes/routes.js index 21dbe6166..384c2c737 100644 --- a/src/routes/routes.js +++ b/src/routes/routes.js @@ -37,7 +37,7 @@ const loginApiRoute = require('./api/login.js'); const recentNotesRoute = require('./api/recent_notes.js'); const appInfoRoute = require('./api/app_info'); const exportRoute = require('./api/export'); -const importRoute = require('./api/import.js'); +const importRoute = require('./api/import'); const setupApiRoute = require('./api/setup.js'); const sqlRoute = require('./api/sql'); const databaseRoute = require('./api/database'); diff --git a/src/services/import/enex.ts b/src/services/import/enex.ts index 8277ae1bd..5e715a0ca 100644 --- a/src/services/import/enex.ts +++ b/src/services/import/enex.ts @@ -55,7 +55,7 @@ interface Note { let note: Partial = {}; let resource: Resource; -function importEnex(taskContext: TaskContext, file: File, parentNote: BNote) { +function importEnex(taskContext: TaskContext, file: File, parentNote: BNote): Promise { const saxStream = sax.createStream(true); const rootNoteTitle = file.originalname.toLowerCase().endsWith(".enex") diff --git a/src/services/task_context.ts b/src/services/task_context.ts index bacf3e8f8..27f7d1358 100644 --- a/src/services/task_context.ts +++ b/src/services/task_context.ts @@ -66,7 +66,7 @@ class TaskContext { }); } - taskSucceeded(result?: string) { + taskSucceeded(result?: string | Record) { ws.sendMessageToAllClients({ type: 'taskSucceeded', taskId: this.taskId, diff --git a/src/services/ws.ts b/src/services/ws.ts index 1b581d358..f3217bfd2 100644 --- a/src/services/ws.ts +++ b/src/services/ws.ts @@ -42,7 +42,7 @@ interface Message { taskType?: string | null; message?: string; reason?: string; - result?: string; + result?: string | Record; script?: string; params?: any[];