diff --git a/packages/lib/services/interop/InteropService.test.ts b/packages/lib/services/interop/InteropService.test.ts index bf8076845b..eb17d606eb 100644 --- a/packages/lib/services/interop/InteropService.test.ts +++ b/packages/lib/services/interop/InteropService.test.ts @@ -545,8 +545,6 @@ describe('services_InteropService', function() { const exportedResource = (result.items.find(i => i.type === ModelType.Resource)).object as ResourceEntity; expect(exportedResource.share_id).toBe(''); expect(exportedResource.is_shared).toBe(0); - - console.info(result.items); })); it('should allow registering new import modules', (async () => { diff --git a/packages/lib/services/interop/InteropService.ts b/packages/lib/services/interop/InteropService.ts index 8006a729c2..e3011f471d 100644 --- a/packages/lib/services/interop/InteropService.ts +++ b/packages/lib/services/interop/InteropService.ts @@ -27,19 +27,19 @@ export default class InteropService { return this.instance_; } - constructor() { + public constructor() { this.eventEmitter_ = new EventEmitter(); } - on(eventName: string, callback: Function) { + public on(eventName: string, callback: Function) { return this.eventEmitter_.on(eventName, callback); } - off(eventName: string, callback: Function) { + public off(eventName: string, callback: Function) { return this.eventEmitter_.removeListener(eventName, callback); } - modules() { + public modules() { if (!this.defaultModules_) { const importModules: Module[] = [ { @@ -156,7 +156,7 @@ export default class InteropService { // or exporters, such as ENEX. In this case, the one marked as "isDefault" // is returned. This is useful to auto-detect the module based on the format. // For more precise matching, newModuleFromPath_ should be used. - findModuleByFormat_(type: ModuleType, format: string, target: FileSystemItem = null, outputFormat: ImportModuleOutputFormat = null) { + private findModuleByFormat_(type: ModuleType, format: string, target: FileSystemItem = null, outputFormat: ImportModuleOutputFormat = null) { const modules = this.modules(); const matches = []; for (let i = 0; i < modules.length; i++) { @@ -203,7 +203,7 @@ export default class InteropService { * https://github.com/laurent22/joplin/pull/1795#discussion_r322379121) but * we can do it if it ever becomes necessary. */ - newModuleByFormat_(type: ModuleType, format: string, outputFormat: ImportModuleOutputFormat = ImportModuleOutputFormat.Markdown) { + private newModuleByFormat_(type: ModuleType, format: string, outputFormat: ImportModuleOutputFormat = ImportModuleOutputFormat.Markdown) { const moduleMetadata = this.findModuleByFormat_(type, format, null, outputFormat); if (!moduleMetadata) throw new Error(_('Cannot load "%s" module for format "%s" and output "%s"', type, format, outputFormat)); @@ -229,7 +229,7 @@ export default class InteropService { * * https://github.com/laurent22/joplin/pull/1795#pullrequestreview-281574417 */ - newModuleFromPath_(type: ModuleType, options: any) { + private newModuleFromPath_(type: ModuleType, options: any) { const moduleMetadata = this.findModuleByFormat_(type, options.format, options.target); if (!moduleMetadata) throw new Error(_('Cannot load "%s" module for format "%s" and target "%s"', type, options.format, options.target)); @@ -246,32 +246,9 @@ export default class InteropService { output.setMetadata({ options, ...moduleMetadata }); return output; - - // let modulePath = options && options.modulePath ? options.modulePath : ''; - - // if (!modulePath) { - // const moduleMetadata = this.findModuleByFormat_(type, options.format, options.target); - // if (!moduleMetadata) throw new Error(_('Cannot load "%s" module for format "%s" and target "%s"', type, options.format, options.target)); - // modulePath = this.modulePath(moduleMetadata); - // } - - // const moduleMetadata = this.findModuleByFormat_(type, options.format, options.target); - - // let output = null; - - // if (moduleMetadata.isCustom) { - // output = this.newModuleFromCustomFactory(moduleMetadata); - // } else { - // const ModuleClass = shim.requireDynamic(modulePath).default; - // output = new ModuleClass(); - // } - - // output.setMetadata({ options, ...moduleMetadata }); - - // return output; } - moduleByFileExtension_(type: ModuleType, ext: string) { + private moduleByFileExtension_(type: ModuleType, ext: string) { ext = ext.toLowerCase(); const modules = this.modules(); diff --git a/packages/server/src/models/UserModel.ts b/packages/server/src/models/UserModel.ts index 002cf348fd..7f14378746 100644 --- a/packages/server/src/models/UserModel.ts +++ b/packages/server/src/models/UserModel.ts @@ -1,7 +1,7 @@ import BaseModel, { AclAction, SaveOptions, ValidateOptions } from './BaseModel'; import { EmailSender, Item, NotificationLevel, Subscription, User, UserFlagType, Uuid } from '../services/database/types'; import * as auth from '../utils/auth'; -import { ErrorUnprocessableEntity, ErrorForbidden, ErrorPayloadTooLarge, ErrorNotFound } from '../utils/errors'; +import { ErrorUnprocessableEntity, ErrorForbidden, ErrorPayloadTooLarge, ErrorNotFound, ErrorBadRequest } from '../utils/errors'; import { ModelType } from '@joplin/lib/BaseModel'; import { _ } from '@joplin/lib/locale'; import { formatBytes, GB, MB } from '../utils/bytes'; @@ -600,7 +600,12 @@ export default class UserModel extends BaseModel { private async syncInfo(userId: Uuid): Promise { const item = await this.models().item().loadByName(userId, 'info.json'); - if (!item) throw new Error('Cannot find info.json file'); + + // We can get there if user 1 tries to share a notebook with user 2, but + // user 2 has never initiated a sync. In this case, they won't have the + // info.json file that we need, so we try to return an error message + // that makes sense. + if (!item) throw new ErrorBadRequest('The account of this user is not correctly initialised (missing info.json)'); const withContent = await this.models().item().loadWithContent(item.id); return JSON.parse(withContent.content.toString()); }