mirror of
https://github.com/laurent22/joplin.git
synced 2025-01-08 13:06:15 +02:00
Chore: Refactor InteropService to not use dynamic imports (#8454)
This commit is contained in:
parent
93e4004033
commit
d95d6733a1
@ -638,6 +638,8 @@ packages/lib/services/interop/InteropService_Importer_Md_frontmatter.js
|
|||||||
packages/lib/services/interop/InteropService_Importer_Md_frontmatter.test.js
|
packages/lib/services/interop/InteropService_Importer_Md_frontmatter.test.js
|
||||||
packages/lib/services/interop/InteropService_Importer_Raw.js
|
packages/lib/services/interop/InteropService_Importer_Raw.js
|
||||||
packages/lib/services/interop/InteropService_Importer_Raw.test.js
|
packages/lib/services/interop/InteropService_Importer_Raw.test.js
|
||||||
|
packages/lib/services/interop/Module.js
|
||||||
|
packages/lib/services/interop/Module.test.js
|
||||||
packages/lib/services/interop/types.js
|
packages/lib/services/interop/types.js
|
||||||
packages/lib/services/joplinServer/personalizedUserContentBaseUrl.js
|
packages/lib/services/joplinServer/personalizedUserContentBaseUrl.js
|
||||||
packages/lib/services/keychain/KeychainService.js
|
packages/lib/services/keychain/KeychainService.js
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -623,6 +623,8 @@ packages/lib/services/interop/InteropService_Importer_Md_frontmatter.js
|
|||||||
packages/lib/services/interop/InteropService_Importer_Md_frontmatter.test.js
|
packages/lib/services/interop/InteropService_Importer_Md_frontmatter.test.js
|
||||||
packages/lib/services/interop/InteropService_Importer_Raw.js
|
packages/lib/services/interop/InteropService_Importer_Raw.js
|
||||||
packages/lib/services/interop/InteropService_Importer_Raw.test.js
|
packages/lib/services/interop/InteropService_Importer_Raw.test.js
|
||||||
|
packages/lib/services/interop/Module.js
|
||||||
|
packages/lib/services/interop/Module.test.js
|
||||||
packages/lib/services/interop/types.js
|
packages/lib/services/interop/types.js
|
||||||
packages/lib/services/joplinServer/personalizedUserContentBaseUrl.js
|
packages/lib/services/joplinServer/personalizedUserContentBaseUrl.js
|
||||||
packages/lib/services/keychain/KeychainService.js
|
packages/lib/services/keychain/KeychainService.js
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import InteropService from '@joplin/lib/services/interop/InteropService';
|
import InteropService from '@joplin/lib/services/interop/InteropService';
|
||||||
import CommandService from '@joplin/lib/services/CommandService';
|
import CommandService from '@joplin/lib/services/CommandService';
|
||||||
import shim from '@joplin/lib/shim';
|
import shim from '@joplin/lib/shim';
|
||||||
import { ExportOptions, FileSystemItem, Module } from '@joplin/lib/services/interop/types';
|
import { ExportOptions, FileSystemItem } from '@joplin/lib/services/interop/types';
|
||||||
|
import { ExportModule } from '@joplin/lib/services/interop/Module';
|
||||||
|
|
||||||
import { _ } from '@joplin/lib/locale';
|
import { _ } from '@joplin/lib/locale';
|
||||||
import { PluginStates } from '@joplin/lib/services/plugins/reducer';
|
import { PluginStates } from '@joplin/lib/services/plugins/reducer';
|
||||||
@ -152,7 +153,7 @@ export default class InteropServiceHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
|
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
|
||||||
public static async export(_dispatch: Function, module: Module, options: ExportNoteOptions = null) {
|
public static async export(_dispatch: Function, module: ExportModule, options: ExportNoteOptions = null) {
|
||||||
if (!options) options = {};
|
if (!options) options = {};
|
||||||
|
|
||||||
let path = null;
|
let path = null;
|
||||||
|
@ -9,7 +9,7 @@ import { PluginStates, utils as pluginUtils } from '@joplin/lib/services/plugins
|
|||||||
import shim from '@joplin/lib/shim';
|
import shim from '@joplin/lib/shim';
|
||||||
import Setting from '@joplin/lib/models/Setting';
|
import Setting from '@joplin/lib/models/Setting';
|
||||||
import versionInfo from '@joplin/lib/versionInfo';
|
import versionInfo from '@joplin/lib/versionInfo';
|
||||||
import { Module } from '@joplin/lib/services/interop/types';
|
import { ImportModule } from '@joplin/lib/services/interop/Module';
|
||||||
import InteropServiceHelper from '../InteropServiceHelper';
|
import InteropServiceHelper from '../InteropServiceHelper';
|
||||||
import { _ } from '@joplin/lib/locale';
|
import { _ } from '@joplin/lib/locale';
|
||||||
import { isContextMenuItemLocation, MenuItem, MenuItemLocation } from '@joplin/lib/services/plugins/api/types';
|
import { isContextMenuItemLocation, MenuItem, MenuItemLocation } from '@joplin/lib/services/plugins/api/types';
|
||||||
@ -230,7 +230,7 @@ function useMenu(props: Props) {
|
|||||||
void CommandService.instance().execute(commandName);
|
void CommandService.instance().execute(commandName);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onImportModuleClick = useCallback(async (module: Module, moduleSource: string) => {
|
const onImportModuleClick = useCallback(async (module: ImportModule, moduleSource: string) => {
|
||||||
let path = null;
|
let path = null;
|
||||||
|
|
||||||
if (moduleSource === 'file') {
|
if (moduleSource === 'file') {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import InteropService from '../../services/interop/InteropService';
|
import InteropService from '../../services/interop/InteropService';
|
||||||
import { CustomExportContext, CustomImportContext, Module, ModuleType } from '../../services/interop/types';
|
import { CustomExportContext, CustomImportContext, ModuleType } from '../../services/interop/types';
|
||||||
import shim from '../../shim';
|
import shim from '../../shim';
|
||||||
import { fileContentEqual, setupDatabaseAndSynchronizer, switchClient, checkThrowAsync, exportDir, supportDir } from '../../testing/test-utils';
|
import { fileContentEqual, setupDatabaseAndSynchronizer, switchClient, checkThrowAsync, exportDir, supportDir } from '../../testing/test-utils';
|
||||||
import Folder from '../../models/Folder';
|
import Folder from '../../models/Folder';
|
||||||
@ -10,6 +10,9 @@ import * as fs from 'fs-extra';
|
|||||||
import { FolderEntity, NoteEntity, ResourceEntity } from '../database/types';
|
import { FolderEntity, NoteEntity, ResourceEntity } from '../database/types';
|
||||||
import { ModelType } from '../../BaseModel';
|
import { ModelType } from '../../BaseModel';
|
||||||
import * as ArrayUtils from '../../ArrayUtils';
|
import * as ArrayUtils from '../../ArrayUtils';
|
||||||
|
import InteropService_Importer_Custom from './InteropService_Importer_Custom';
|
||||||
|
import InteropService_Exporter_Custom from './InteropService_Exporter_Custom';
|
||||||
|
import Module, { makeExportModule, makeImportModule } from './Module';
|
||||||
|
|
||||||
async function recreateExportDir() {
|
async function recreateExportDir() {
|
||||||
const dir = exportDir();
|
const dir = exportDir();
|
||||||
@ -47,13 +50,12 @@ function memoryExportModule() {
|
|||||||
resources: [],
|
resources: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const module: Module = {
|
const module: Module = makeExportModule({
|
||||||
type: ModuleType.Exporter,
|
|
||||||
description: 'Memory Export Module',
|
description: 'Memory Export Module',
|
||||||
format: 'memory',
|
format: 'memory',
|
||||||
fileExtensions: ['memory'],
|
fileExtensions: ['memory'],
|
||||||
isCustom: true,
|
}, () => {
|
||||||
|
return new InteropService_Exporter_Custom({
|
||||||
onInit: async (context: CustomExportContext) => {
|
onInit: async (context: CustomExportContext) => {
|
||||||
result.destPath = context.destPath;
|
result.destPath = context.destPath;
|
||||||
},
|
},
|
||||||
@ -75,7 +77,8 @@ function memoryExportModule() {
|
|||||||
onClose: async (_context: CustomExportContext) => {
|
onClose: async (_context: CustomExportContext) => {
|
||||||
// nothing
|
// nothing
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return { result, module };
|
return { result, module };
|
||||||
}
|
}
|
||||||
@ -555,18 +558,19 @@ describe('services_InteropService', () => {
|
|||||||
sourcePath: '',
|
sourcePath: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
const module: Module = {
|
const module = makeImportModule({
|
||||||
type: ModuleType.Importer,
|
type: ModuleType.Importer,
|
||||||
description: 'Test Import Module',
|
description: 'Test Import Module',
|
||||||
format: 'testing',
|
format: 'testing',
|
||||||
fileExtensions: ['test'],
|
fileExtensions: ['test'],
|
||||||
isCustom: true,
|
}, () => {
|
||||||
|
return new InteropService_Importer_Custom({
|
||||||
onExec: async (context: CustomImportContext) => {
|
onExec: async (context: CustomImportContext) => {
|
||||||
result.hasBeenExecuted = true;
|
result.hasBeenExecuted = true;
|
||||||
result.sourcePath = context.sourcePath;
|
result.sourcePath = context.sourcePath;
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const service = InteropService.instance();
|
const service = InteropService.instance();
|
||||||
service.registerModule(module);
|
service.registerModule(module);
|
||||||
@ -596,13 +600,13 @@ describe('services_InteropService', () => {
|
|||||||
closeCalled: false,
|
closeCalled: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const module: Module = {
|
const module: Module = makeExportModule({
|
||||||
type: ModuleType.Exporter,
|
type: ModuleType.Exporter,
|
||||||
description: 'Test Export Module',
|
description: 'Test Export Module',
|
||||||
format: 'testing',
|
format: 'testing',
|
||||||
fileExtensions: ['test'],
|
fileExtensions: ['test'],
|
||||||
isCustom: true,
|
}, () => {
|
||||||
|
return new InteropService_Exporter_Custom({
|
||||||
onInit: async (context: CustomExportContext) => {
|
onInit: async (context: CustomExportContext) => {
|
||||||
result.destPath = context.destPath;
|
result.destPath = context.destPath;
|
||||||
},
|
},
|
||||||
@ -620,7 +624,8 @@ describe('services_InteropService', () => {
|
|||||||
onClose: async (_context: CustomExportContext) => {
|
onClose: async (_context: CustomExportContext) => {
|
||||||
result.closeCalled = true;
|
result.closeCalled = true;
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const service = InteropService.instance();
|
const service = InteropService.instance();
|
||||||
service.registerModule(module);
|
service.registerModule(module);
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { ModuleType, FileSystemItem, ImportModuleOutputFormat, Module, ImportOptions, ExportOptions, ImportExportResult, defaultImportExportModule } from './types';
|
import { ModuleType, FileSystemItem, ImportModuleOutputFormat, ImportOptions, ExportOptions, ImportExportResult } from './types';
|
||||||
import InteropService_Importer_Custom from './InteropService_Importer_Custom';
|
|
||||||
import InteropService_Exporter_Custom from './InteropService_Exporter_Custom';
|
|
||||||
import shim from '../../shim';
|
import shim from '../../shim';
|
||||||
import { _ } from '../../locale';
|
import { _ } from '../../locale';
|
||||||
import BaseItem from '../../models/BaseItem';
|
import BaseItem from '../../models/BaseItem';
|
||||||
@ -10,9 +8,22 @@ import Folder from '../../models/Folder';
|
|||||||
import NoteTag from '../../models/NoteTag';
|
import NoteTag from '../../models/NoteTag';
|
||||||
import Note from '../../models/Note';
|
import Note from '../../models/Note';
|
||||||
import * as ArrayUtils from '../../ArrayUtils';
|
import * as ArrayUtils from '../../ArrayUtils';
|
||||||
|
import InteropService_Importer_Jex from './InteropService_Importer_Jex';
|
||||||
|
import InteropService_Importer_Md from './InteropService_Importer_Md';
|
||||||
|
import InteropService_Importer_Md_frontmatter from './InteropService_Importer_Md_frontmatter';
|
||||||
|
import InteropService_Importer_Raw from './InteropService_Importer_Raw';
|
||||||
|
import InteropService_Importer_EnexToMd from './InteropService_Importer_EnexToMd';
|
||||||
|
import InteropService_Importer_EnexToHtml from './InteropService_Importer_EnexToHtml';
|
||||||
|
import InteropService_Exporter_Jex from './InteropService_Exporter_Jex';
|
||||||
|
import InteropService_Exporter_Raw from './InteropService_Exporter_Raw';
|
||||||
|
import InteropService_Exporter_Md from './InteropService_Exporter_Md';
|
||||||
|
import InteropService_Exporter_Md_frontmatter from './InteropService_Exporter_Md_frontmatter';
|
||||||
|
import InteropService_Exporter_Html from './InteropService_Exporter_Html';
|
||||||
|
import InteropService_Importer_Base from './InteropService_Importer_Base';
|
||||||
|
import InteropService_Exporter_Base from './InteropService_Exporter_Base';
|
||||||
|
import Module, { makeExportModule, makeImportModule } from './Module';
|
||||||
const { sprintf } = require('sprintf-js');
|
const { sprintf } = require('sprintf-js');
|
||||||
const { fileExtension } = require('../../path-utils');
|
const { fileExtension } = require('../../path-utils');
|
||||||
const { toTitleCase } = require('../../string-utils');
|
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
|
|
||||||
export default class InteropService {
|
export default class InteropService {
|
||||||
@ -43,47 +54,46 @@ export default class InteropService {
|
|||||||
|
|
||||||
public modules() {
|
public modules() {
|
||||||
if (!this.defaultModules_) {
|
if (!this.defaultModules_) {
|
||||||
const importModules: Module[] = [
|
const importModules = [
|
||||||
{
|
makeImportModule({
|
||||||
...defaultImportExportModule(ModuleType.Importer),
|
|
||||||
format: 'jex',
|
format: 'jex',
|
||||||
fileExtensions: ['jex'],
|
fileExtensions: ['jex'],
|
||||||
sources: [FileSystemItem.File],
|
sources: [FileSystemItem.File],
|
||||||
description: _('Joplin Export File'),
|
description: _('Joplin Export File'),
|
||||||
},
|
}, () => new InteropService_Importer_Jex()),
|
||||||
{
|
|
||||||
...defaultImportExportModule(ModuleType.Importer),
|
makeImportModule({
|
||||||
format: 'md',
|
format: 'md',
|
||||||
fileExtensions: ['md', 'markdown', 'txt', 'html'],
|
fileExtensions: ['md', 'markdown', 'txt', 'html'],
|
||||||
sources: [FileSystemItem.File, FileSystemItem.Directory],
|
sources: [FileSystemItem.File, FileSystemItem.Directory],
|
||||||
isNoteArchive: false, // Tells whether the file can contain multiple notes (eg. Enex or Jex format)
|
isNoteArchive: false, // Tells whether the file can contain multiple notes (eg. Enex or Jex format)
|
||||||
description: _('Markdown'),
|
description: _('Markdown'),
|
||||||
},
|
}, () => new InteropService_Importer_Md()),
|
||||||
{
|
|
||||||
...defaultImportExportModule(ModuleType.Importer),
|
makeImportModule({
|
||||||
format: 'md_frontmatter',
|
format: 'md_frontmatter',
|
||||||
fileExtensions: ['md', 'markdown', 'txt', 'html'],
|
fileExtensions: ['md', 'markdown', 'txt', 'html'],
|
||||||
sources: [FileSystemItem.File, FileSystemItem.Directory],
|
sources: [FileSystemItem.File, FileSystemItem.Directory],
|
||||||
isNoteArchive: false, // Tells whether the file can contain multiple notes (eg. Enex or Jex format)
|
isNoteArchive: false, // Tells whether the file can contain multiple notes (eg. Enex or Jex format)
|
||||||
description: _('Markdown + Front Matter'),
|
description: _('Markdown + Front Matter'),
|
||||||
},
|
}, () => new InteropService_Importer_Md_frontmatter()),
|
||||||
{
|
|
||||||
...defaultImportExportModule(ModuleType.Importer),
|
makeImportModule({
|
||||||
format: 'raw',
|
format: 'raw',
|
||||||
sources: [FileSystemItem.Directory],
|
sources: [FileSystemItem.Directory],
|
||||||
description: _('Joplin Export Directory'),
|
description: _('Joplin Export Directory'),
|
||||||
},
|
}, () => new InteropService_Importer_Raw()),
|
||||||
{
|
|
||||||
...defaultImportExportModule(ModuleType.Importer),
|
makeImportModule({
|
||||||
format: 'enex',
|
format: 'enex',
|
||||||
fileExtensions: ['enex'],
|
fileExtensions: ['enex'],
|
||||||
sources: [FileSystemItem.File],
|
sources: [FileSystemItem.File],
|
||||||
description: _('Evernote Export File (as Markdown)'),
|
description: _('Evernote Export File (as Markdown)'),
|
||||||
importerClass: 'InteropService_Importer_EnexToMd',
|
importerClass: 'InteropService_Importer_EnexToMd',
|
||||||
isDefault: true,
|
isDefault: true,
|
||||||
},
|
}, () => new InteropService_Importer_EnexToMd()),
|
||||||
{
|
|
||||||
...defaultImportExportModule(ModuleType.Importer),
|
makeImportModule({
|
||||||
format: 'enex',
|
format: 'enex',
|
||||||
fileExtensions: ['enex'],
|
fileExtensions: ['enex'],
|
||||||
sources: [FileSystemItem.File],
|
sources: [FileSystemItem.File],
|
||||||
@ -91,65 +101,58 @@ export default class InteropService {
|
|||||||
// TODO: Consider doing this the same way as the multiple `md` importers are handled
|
// TODO: Consider doing this the same way as the multiple `md` importers are handled
|
||||||
importerClass: 'InteropService_Importer_EnexToHtml',
|
importerClass: 'InteropService_Importer_EnexToHtml',
|
||||||
outputFormat: ImportModuleOutputFormat.Html,
|
outputFormat: ImportModuleOutputFormat.Html,
|
||||||
},
|
}, () => new InteropService_Importer_EnexToHtml()),
|
||||||
];
|
];
|
||||||
|
|
||||||
const exportModules: Module[] = [
|
const exportModules = [
|
||||||
{
|
makeExportModule({
|
||||||
...defaultImportExportModule(ModuleType.Exporter),
|
|
||||||
format: 'jex',
|
format: 'jex',
|
||||||
fileExtensions: ['jex'],
|
fileExtensions: ['jex'],
|
||||||
target: FileSystemItem.File,
|
target: FileSystemItem.File,
|
||||||
description: _('Joplin Export File'),
|
description: _('Joplin Export File'),
|
||||||
},
|
}, () => new InteropService_Exporter_Jex()),
|
||||||
{
|
|
||||||
...defaultImportExportModule(ModuleType.Exporter),
|
makeExportModule({
|
||||||
format: 'raw',
|
format: 'raw',
|
||||||
target: FileSystemItem.Directory,
|
target: FileSystemItem.Directory,
|
||||||
description: _('Joplin Export Directory'),
|
description: _('Joplin Export Directory'),
|
||||||
},
|
}, () => new InteropService_Exporter_Raw()),
|
||||||
{
|
|
||||||
...defaultImportExportModule(ModuleType.Exporter),
|
makeExportModule({
|
||||||
format: 'md',
|
format: 'md',
|
||||||
target: FileSystemItem.Directory,
|
target: FileSystemItem.Directory,
|
||||||
description: _('Markdown'),
|
description: _('Markdown'),
|
||||||
},
|
}, () => new InteropService_Exporter_Md()),
|
||||||
{
|
|
||||||
...defaultImportExportModule(ModuleType.Exporter),
|
makeExportModule({
|
||||||
format: 'md_frontmatter',
|
format: 'md_frontmatter',
|
||||||
target: FileSystemItem.Directory,
|
target: FileSystemItem.Directory,
|
||||||
description: _('Markdown + Front Matter'),
|
description: _('Markdown + Front Matter'),
|
||||||
},
|
}, () => new InteropService_Exporter_Md_frontmatter()),
|
||||||
{
|
|
||||||
...defaultImportExportModule(ModuleType.Exporter),
|
makeExportModule({
|
||||||
format: 'html',
|
format: 'html',
|
||||||
fileExtensions: ['html', 'htm'],
|
fileExtensions: ['html', 'htm'],
|
||||||
target: FileSystemItem.File,
|
target: FileSystemItem.File,
|
||||||
isNoteArchive: false,
|
isNoteArchive: false,
|
||||||
description: _('HTML File'),
|
description: _('HTML File'),
|
||||||
},
|
}, () => new InteropService_Exporter_Html()),
|
||||||
{
|
|
||||||
...defaultImportExportModule(ModuleType.Exporter),
|
makeExportModule({
|
||||||
format: 'html',
|
format: 'html',
|
||||||
target: FileSystemItem.Directory,
|
target: FileSystemItem.Directory,
|
||||||
description: _('HTML Directory'),
|
description: _('HTML Directory'),
|
||||||
},
|
}, () => new InteropService_Exporter_Html()),
|
||||||
];
|
];
|
||||||
|
|
||||||
this.defaultModules_ = importModules.concat(exportModules);
|
this.defaultModules_ = (importModules as Module[]).concat(exportModules);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.defaultModules_.concat(this.userModules_);
|
return this.defaultModules_.concat(this.userModules_);
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerModule(module: Module) {
|
public registerModule(module: Module) {
|
||||||
module = {
|
|
||||||
...defaultImportExportModule(module.type),
|
|
||||||
...module,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.userModules_.push(module);
|
this.userModules_.push(module);
|
||||||
|
|
||||||
this.eventEmitter_.emit('modulesChanged');
|
this.eventEmitter_.emit('modulesChanged');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,9 +169,13 @@ export default class InteropService {
|
|||||||
if (m.format === format && m.type === type) {
|
if (m.format === format && m.type === type) {
|
||||||
if (!target && !outputFormat) {
|
if (!target && !outputFormat) {
|
||||||
matches.push(m);
|
matches.push(m);
|
||||||
} else if (target && target === m.target) {
|
} else if (
|
||||||
|
m.type === ModuleType.Exporter && target && target === m.target
|
||||||
|
) {
|
||||||
matches.push(m);
|
matches.push(m);
|
||||||
} else if (outputFormat && outputFormat === m.outputFormat) {
|
} else if (
|
||||||
|
m.type === ModuleType.Importer && outputFormat && outputFormat === m.outputFormat
|
||||||
|
) {
|
||||||
matches.push(m);
|
matches.push(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -180,24 +187,6 @@ export default class InteropService {
|
|||||||
return matches.length ? matches[0] : null;
|
return matches.length ? matches[0] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private modulePath(module: Module) {
|
|
||||||
let className = '';
|
|
||||||
if (module.type === ModuleType.Importer) {
|
|
||||||
className = module.importerClass || `InteropService_Importer_${toTitleCase(module.format)}`;
|
|
||||||
} else {
|
|
||||||
className = `InteropService_Exporter_${toTitleCase(module.format)}`;
|
|
||||||
}
|
|
||||||
return `./${className}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private newModuleFromCustomFactory(module: Module) {
|
|
||||||
if (module.type === ModuleType.Importer) {
|
|
||||||
return new InteropService_Importer_Custom(module);
|
|
||||||
} else {
|
|
||||||
return new InteropService_Exporter_Custom(module);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE TO FUTURE SELF: It might make sense to simply move all the existing
|
// NOTE TO FUTURE SELF: It might make sense to simply move all the existing
|
||||||
// formatters to the `newModuleFromPath_` approach, so that there's only one way
|
// formatters to the `newModuleFromPath_` approach, so that there's only one way
|
||||||
// to do this mapping. This isn't a priority right now (per the convo in:
|
// to do this mapping. This isn't a priority right now (per the convo in:
|
||||||
@ -207,18 +196,7 @@ export default class InteropService {
|
|||||||
const moduleMetadata = this.findModuleByFormat_(type, format, null, outputFormat);
|
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));
|
if (!moduleMetadata) throw new Error(_('Cannot load "%s" module for format "%s" and output "%s"', type, format, outputFormat));
|
||||||
|
|
||||||
let output = null;
|
return moduleMetadata.factory();
|
||||||
|
|
||||||
if (moduleMetadata.isCustom) {
|
|
||||||
output = this.newModuleFromCustomFactory(moduleMetadata);
|
|
||||||
} else {
|
|
||||||
const ModuleClass = shim.requireDynamic(this.modulePath(moduleMetadata)).default;
|
|
||||||
output = new ModuleClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
output.setMetadata(moduleMetadata);
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The existing `newModuleByFormat_` fn would load by the input format. This
|
// The existing `newModuleByFormat_` fn would load by the input format. This
|
||||||
@ -231,19 +209,7 @@ export default class InteropService {
|
|||||||
const moduleMetadata = this.findModuleByFormat_(type, options.format, options.target);
|
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));
|
if (!moduleMetadata) throw new Error(_('Cannot load "%s" module for format "%s" and target "%s"', type, options.format, options.target));
|
||||||
|
|
||||||
let output = null;
|
return moduleMetadata.factory(options);
|
||||||
|
|
||||||
if (moduleMetadata.isCustom) {
|
|
||||||
output = this.newModuleFromCustomFactory(moduleMetadata);
|
|
||||||
} else {
|
|
||||||
const modulePath = this.modulePath(moduleMetadata);
|
|
||||||
const ModuleClass = shim.requireDynamic(modulePath).default;
|
|
||||||
output = new ModuleClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
output.setMetadata({ options, ...moduleMetadata });
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private moduleByFileExtension_(type: ModuleType, ext: string) {
|
private moduleByFileExtension_(type: ModuleType, ext: string) {
|
||||||
@ -254,7 +220,7 @@ export default class InteropService {
|
|||||||
for (let i = 0; i < modules.length; i++) {
|
for (let i = 0; i < modules.length; i++) {
|
||||||
const m = modules[i];
|
const m = modules[i];
|
||||||
if (type !== m.type) continue;
|
if (type !== m.type) continue;
|
||||||
if (m.fileExtensions && m.fileExtensions.indexOf(ext) >= 0) return m;
|
if (m.fileExtensions.includes(ext)) return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -273,14 +239,12 @@ export default class InteropService {
|
|||||||
if (options.format === 'auto') {
|
if (options.format === 'auto') {
|
||||||
const module = this.moduleByFileExtension_(ModuleType.Importer, fileExtension(options.path));
|
const module = this.moduleByFileExtension_(ModuleType.Importer, fileExtension(options.path));
|
||||||
if (!module) throw new Error(_('Please specify import format for %s', options.path));
|
if (!module) throw new Error(_('Please specify import format for %s', options.path));
|
||||||
// eslint-disable-next-line require-atomic-updates
|
|
||||||
options.format = module.format;
|
options.format = module.format;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.destinationFolderId) {
|
if (options.destinationFolderId) {
|
||||||
const folder = await Folder.load(options.destinationFolderId);
|
const folder = await Folder.load(options.destinationFolderId);
|
||||||
if (!folder) throw new Error(_('Cannot find "%s".', options.destinationFolderId));
|
if (!folder) throw new Error(_('Cannot find "%s".', options.destinationFolderId));
|
||||||
// eslint-disable-next-line require-atomic-updates
|
|
||||||
options.destinationFolder = folder;
|
options.destinationFolder = folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,6 +252,10 @@ export default class InteropService {
|
|||||||
|
|
||||||
const importer = this.newModuleByFormat_(ModuleType.Importer, options.format, options.outputFormat);
|
const importer = this.newModuleByFormat_(ModuleType.Importer, options.format, options.outputFormat);
|
||||||
|
|
||||||
|
if (!(importer instanceof InteropService_Importer_Base)) {
|
||||||
|
throw new Error('Resolved importer is not an importer');
|
||||||
|
}
|
||||||
|
|
||||||
await importer.init(options.path, options);
|
await importer.init(options.path, options);
|
||||||
result = await importer.exec(result);
|
result = await importer.exec(result);
|
||||||
|
|
||||||
@ -386,6 +354,10 @@ export default class InteropService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const exporter = this.newModuleFromPath_(ModuleType.Exporter, options);
|
const exporter = this.newModuleFromPath_(ModuleType.Exporter, options);
|
||||||
|
if (!(exporter instanceof InteropService_Exporter_Base)) {
|
||||||
|
throw new Error('Resolved exporter is not an exporter');
|
||||||
|
}
|
||||||
|
|
||||||
await exporter.init(exportPath, options);
|
await exporter.init(exportPath, options);
|
||||||
|
|
||||||
const typeOrder = [BaseModel.TYPE_FOLDER, BaseModel.TYPE_RESOURCE, BaseModel.TYPE_NOTE, BaseModel.TYPE_TAG, BaseModel.TYPE_NOTE_TAG];
|
const typeOrder = [BaseModel.TYPE_FOLDER, BaseModel.TYPE_RESOURCE, BaseModel.TYPE_NOTE, BaseModel.TYPE_TAG, BaseModel.TYPE_NOTE_TAG];
|
||||||
|
@ -1,13 +1,20 @@
|
|||||||
import { ExportContext } from '../plugins/api/types';
|
import { ExportContext } from '../plugins/api/types';
|
||||||
import InteropService_Exporter_Base from './InteropService_Exporter_Base';
|
import InteropService_Exporter_Base from './InteropService_Exporter_Base';
|
||||||
import { ExportOptions, Module } from './types';
|
import { ExportOptions } from './types';
|
||||||
|
|
||||||
|
interface CustomImporter {
|
||||||
|
onInit(context: any): Promise<void>;
|
||||||
|
onProcessItem(context: any, itemType: number, item: any): Promise<void>;
|
||||||
|
onProcessResource(context: any, resource: any, filePath: string): Promise<void>;
|
||||||
|
onClose(context: any): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
export default class InteropService_Exporter_Custom extends InteropService_Exporter_Base {
|
export default class InteropService_Exporter_Custom extends InteropService_Exporter_Base {
|
||||||
|
|
||||||
private customContext_: ExportContext;
|
private customContext_: ExportContext;
|
||||||
private module_: Module = null;
|
private module_: CustomImporter = null;
|
||||||
|
|
||||||
public constructor(module: Module) {
|
public constructor(module: CustomImporter) {
|
||||||
super();
|
super();
|
||||||
this.module_ = module;
|
this.module_ = module;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
import InteropService_Importer_Base from './InteropService_Importer_Base';
|
import InteropService_Importer_Base from './InteropService_Importer_Base';
|
||||||
import { ImportExportResult, Module } from './types';
|
import { ImportExportResult } from './types';
|
||||||
|
|
||||||
|
interface CustomImporter {
|
||||||
|
onExec(
|
||||||
|
context: { sourcePath: string; options: any; warnings: string[] }
|
||||||
|
): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
export default class InteropService_Importer_Custom extends InteropService_Importer_Base {
|
export default class InteropService_Importer_Custom extends InteropService_Importer_Base {
|
||||||
|
|
||||||
private module_: Module = null;
|
private module_: CustomImporter = null;
|
||||||
|
|
||||||
public constructor(handler: Module) {
|
public constructor(handler: CustomImporter) {
|
||||||
super();
|
super();
|
||||||
this.module_ = handler;
|
this.module_ = handler;
|
||||||
}
|
}
|
||||||
@ -23,10 +29,12 @@ export default class InteropService_Importer_Custom extends InteropService_Impor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.module_.onExec({
|
await this.module_.onExec({
|
||||||
sourcePath: this.sourcePath_,
|
sourcePath: this.sourcePath_,
|
||||||
options: processedOptions,
|
options: processedOptions,
|
||||||
warnings: result.warnings,
|
warnings: result.warnings,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
53
packages/lib/services/interop/Module.test.ts
Normal file
53
packages/lib/services/interop/Module.test.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import InteropService_Exporter_Base from './InteropService_Exporter_Base';
|
||||||
|
import InteropService_Importer_Base from './InteropService_Importer_Base';
|
||||||
|
import { makeExportModule, makeImportModule } from './Module';
|
||||||
|
import { FileSystemItem } from './types';
|
||||||
|
|
||||||
|
describe('Module', () => {
|
||||||
|
it('should return correct default fullLabel for an ImportModule', () => {
|
||||||
|
const baseMetadata = {
|
||||||
|
format: 'Foo_test',
|
||||||
|
description: 'Some description here',
|
||||||
|
sources: [FileSystemItem.File, FileSystemItem.Directory],
|
||||||
|
};
|
||||||
|
|
||||||
|
const importModuleMultiSource = makeImportModule(
|
||||||
|
baseMetadata,
|
||||||
|
() => new InteropService_Importer_Base()
|
||||||
|
);
|
||||||
|
|
||||||
|
const importModuleSingleSource = makeImportModule({
|
||||||
|
...baseMetadata,
|
||||||
|
sources: [FileSystemItem.File],
|
||||||
|
}, () => new InteropService_Importer_Base());
|
||||||
|
|
||||||
|
// The two modules should have the same data, except for their sources.
|
||||||
|
expect(importModuleMultiSource.format).toBe('Foo_test');
|
||||||
|
expect(importModuleSingleSource.format).toBe(importModuleMultiSource.format);
|
||||||
|
expect(importModuleMultiSource.sources).toHaveLength(2);
|
||||||
|
expect(importModuleSingleSource.sources).toHaveLength(1);
|
||||||
|
|
||||||
|
const baseLabel = 'FOO - Some description here';
|
||||||
|
expect(importModuleMultiSource.fullLabel()).toBe(baseLabel);
|
||||||
|
expect(importModuleSingleSource.fullLabel()).toBe(baseLabel);
|
||||||
|
|
||||||
|
// Should only include (File) if the import module has more than one source
|
||||||
|
expect(importModuleMultiSource.fullLabel(FileSystemItem.File)).toBe(`${baseLabel} (File)`);
|
||||||
|
expect(importModuleSingleSource.fullLabel(FileSystemItem.File)).toBe(baseLabel);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct default fullLabel for an ExportModule', () => {
|
||||||
|
const testExportModule = makeExportModule({
|
||||||
|
format: 'format_test_______TEST',
|
||||||
|
description: 'Testing...',
|
||||||
|
}, () => new InteropService_Exporter_Base());
|
||||||
|
|
||||||
|
// Should only include the portion of format before the first underscore
|
||||||
|
const label = 'FORMAT - Testing...';
|
||||||
|
expect(testExportModule.fullLabel()).toBe(label);
|
||||||
|
|
||||||
|
// Sources should only be shown for import modules
|
||||||
|
expect(testExportModule.fullLabel(FileSystemItem.File)).toBe(label);
|
||||||
|
expect(testExportModule.fullLabel(FileSystemItem.Directory)).toBe(label);
|
||||||
|
});
|
||||||
|
});
|
123
packages/lib/services/interop/Module.ts
Normal file
123
packages/lib/services/interop/Module.ts
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
import { _ } from '../../locale';
|
||||||
|
import InteropService_Exporter_Base from './InteropService_Exporter_Base';
|
||||||
|
import InteropService_Importer_Base from './InteropService_Importer_Base';
|
||||||
|
import { ExportOptions, FileSystemItem, ImportModuleOutputFormat, ImportOptions, ModuleType } from './types';
|
||||||
|
|
||||||
|
// Metadata shared between importers and exporters.
|
||||||
|
interface BaseMetadata {
|
||||||
|
format: string;
|
||||||
|
fileExtensions: string[];
|
||||||
|
description: string;
|
||||||
|
isDefault: boolean;
|
||||||
|
|
||||||
|
// Returns the full label to be displayed in the UI.
|
||||||
|
fullLabel(moduleSource?: FileSystemItem): string;
|
||||||
|
|
||||||
|
// Only applies to single file exporters or importers
|
||||||
|
// It tells whether the format can package multiple notes into one file.
|
||||||
|
// For example JEX or ENEX can, but HTML cannot.
|
||||||
|
// Default: true.
|
||||||
|
isNoteArchive: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ImportMetadata extends BaseMetadata {
|
||||||
|
type: ModuleType.Importer;
|
||||||
|
|
||||||
|
sources: FileSystemItem[];
|
||||||
|
importerClass: string;
|
||||||
|
outputFormat: ImportModuleOutputFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ImportModule extends ImportMetadata {
|
||||||
|
factory(options?: ImportOptions): InteropService_Importer_Base;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ExportMetadata extends BaseMetadata {
|
||||||
|
type: ModuleType.Exporter;
|
||||||
|
|
||||||
|
target: FileSystemItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ExportModule extends ExportMetadata {
|
||||||
|
factory(options?: ExportOptions): InteropService_Exporter_Base;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultBaseMetadata = {
|
||||||
|
format: '',
|
||||||
|
fileExtensions: [] as string[],
|
||||||
|
description: '',
|
||||||
|
isNoteArchive: true,
|
||||||
|
isDefault: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const moduleFullLabel = (metadata: ImportMetadata|ExportMetadata, moduleSource: FileSystemItem = null) => {
|
||||||
|
const format = metadata.format.split('_')[0];
|
||||||
|
const label = [`${format.toUpperCase()} - ${metadata.description}`];
|
||||||
|
if (moduleSource && metadata.type === ModuleType.Importer && metadata.sources.length > 1) {
|
||||||
|
label.push(`(${moduleSource === FileSystemItem.File ? _('File') : _('Directory')})`);
|
||||||
|
}
|
||||||
|
return label.join(' ');
|
||||||
|
};
|
||||||
|
|
||||||
|
export const makeImportModule = (
|
||||||
|
metadata: Partial<ImportMetadata>, factory: ()=> InteropService_Importer_Base
|
||||||
|
): ImportModule => {
|
||||||
|
const importerDefaults: ImportMetadata = {
|
||||||
|
...defaultBaseMetadata,
|
||||||
|
type: ModuleType.Importer,
|
||||||
|
sources: [],
|
||||||
|
importerClass: '',
|
||||||
|
outputFormat: ImportModuleOutputFormat.Markdown,
|
||||||
|
|
||||||
|
fullLabel: (moduleSource?: FileSystemItem) => {
|
||||||
|
return moduleFullLabel(fullMetadata, moduleSource);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const fullMetadata = {
|
||||||
|
...importerDefaults,
|
||||||
|
...metadata,
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
...fullMetadata,
|
||||||
|
factory: (options: ImportOptions = {}) => {
|
||||||
|
const result = factory();
|
||||||
|
result.setMetadata({ ...fullMetadata, ...(options ?? {}) });
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const makeExportModule = (
|
||||||
|
metadata: Partial<ExportMetadata>, factory: ()=> InteropService_Exporter_Base
|
||||||
|
): ExportModule => {
|
||||||
|
const exporterDefaults: ExportMetadata = {
|
||||||
|
...defaultBaseMetadata,
|
||||||
|
type: ModuleType.Exporter,
|
||||||
|
target: FileSystemItem.File,
|
||||||
|
|
||||||
|
fullLabel: (moduleSource?: FileSystemItem) => {
|
||||||
|
return moduleFullLabel(fullMetadata, moduleSource);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const fullMetadata = {
|
||||||
|
...exporterDefaults,
|
||||||
|
...metadata,
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
...fullMetadata,
|
||||||
|
factory: (options: ExportOptions = {}) => {
|
||||||
|
const result = factory();
|
||||||
|
result.setMetadata({ ...fullMetadata, ...(options ?? {}) });
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type Module = ImportModule|ExportModule;
|
||||||
|
export default Module;
|
@ -1,4 +1,3 @@
|
|||||||
import { _ } from '../../locale';
|
|
||||||
import { PluginStates } from '../plugins/reducer';
|
import { PluginStates } from '../plugins/reducer';
|
||||||
|
|
||||||
export interface CustomImportContext {
|
export interface CustomImportContext {
|
||||||
@ -27,58 +26,6 @@ export enum ImportModuleOutputFormat {
|
|||||||
Html = 'html',
|
Html = 'html',
|
||||||
}
|
}
|
||||||
|
|
||||||
// For historical reasons the import and export modules share the same
|
|
||||||
// interface, except that some properties are used only for import
|
|
||||||
// and others only for export.
|
|
||||||
export interface Module {
|
|
||||||
// ---------------------------------------
|
|
||||||
// Shared properties
|
|
||||||
// ---------------------------------------
|
|
||||||
|
|
||||||
type: ModuleType;
|
|
||||||
format: string;
|
|
||||||
fileExtensions: string[];
|
|
||||||
description: string;
|
|
||||||
// path?: string;
|
|
||||||
|
|
||||||
// Only applies to single file exporters or importers
|
|
||||||
// It tells whether the format can package multiple notes into one file.
|
|
||||||
// For example JEX or ENEX can, but HTML cannot.
|
|
||||||
// Default: true.
|
|
||||||
isNoteArchive?: boolean;
|
|
||||||
|
|
||||||
// A custom module is one that was not hard-coded, that was created at runtime
|
|
||||||
// by a plugin for example. If `isCustom` is `true` if it is expected that all
|
|
||||||
// the event handlers below are defined (it's enforced by the plugin API).
|
|
||||||
isCustom?: boolean;
|
|
||||||
|
|
||||||
// ---------------------------------------
|
|
||||||
// Import-only properties
|
|
||||||
// ---------------------------------------
|
|
||||||
|
|
||||||
sources?: FileSystemItem[];
|
|
||||||
importerClass?: string;
|
|
||||||
outputFormat?: ImportModuleOutputFormat;
|
|
||||||
isDefault?: boolean;
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
|
|
||||||
fullLabel?: Function;
|
|
||||||
|
|
||||||
// Used only if `isCustom` is true
|
|
||||||
onExec?(context: any): Promise<any>;
|
|
||||||
|
|
||||||
// ---------------------------------------
|
|
||||||
// Export-only properties
|
|
||||||
// ---------------------------------------
|
|
||||||
|
|
||||||
target?: FileSystemItem;
|
|
||||||
|
|
||||||
// Used only if `isCustom` is true
|
|
||||||
onInit?(context: any): Promise<void>;
|
|
||||||
onProcessItem?(context: any, itemType: number, item: any): Promise<void>;
|
|
||||||
onProcessResource?(context: any, resource: any, filePath: string): Promise<void>;
|
|
||||||
onClose?(context: any): Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ImportOptions {
|
export interface ImportOptions {
|
||||||
path?: string;
|
path?: string;
|
||||||
format?: string;
|
format?: string;
|
||||||
@ -119,29 +66,3 @@ export interface MdFrontMatterExport {
|
|||||||
'created'?: string;
|
'created'?: string;
|
||||||
'tags'?: string[];
|
'tags'?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
function moduleFullLabel(moduleSource: FileSystemItem = null): string {
|
|
||||||
const format = this.format.split('_')[0];
|
|
||||||
const label = [`${format.toUpperCase()} - ${this.description}`];
|
|
||||||
if (moduleSource && this.sources.length > 1) {
|
|
||||||
label.push(`(${moduleSource === 'file' ? _('File') : _('Directory')})`);
|
|
||||||
}
|
|
||||||
return label.join(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function defaultImportExportModule(type: ModuleType): Module {
|
|
||||||
return {
|
|
||||||
type: type,
|
|
||||||
format: '',
|
|
||||||
fileExtensions: [],
|
|
||||||
sources: [],
|
|
||||||
description: '',
|
|
||||||
isNoteArchive: true,
|
|
||||||
importerClass: '',
|
|
||||||
outputFormat: ImportModuleOutputFormat.Markdown,
|
|
||||||
isDefault: false,
|
|
||||||
fullLabel: moduleFullLabel,
|
|
||||||
isCustom: false,
|
|
||||||
target: FileSystemItem.File,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
/* eslint-disable multiline-comment-style */
|
/* eslint-disable multiline-comment-style */
|
||||||
|
|
||||||
import InteropService from '../../interop/InteropService';
|
import InteropService from '../../interop/InteropService';
|
||||||
import { Module, ModuleType } from '../../interop/types';
|
import InteropService_Exporter_Custom from '../../interop/InteropService_Exporter_Custom';
|
||||||
|
import InteropService_Importer_Custom from '../../interop/InteropService_Importer_Custom';
|
||||||
|
import { makeExportModule, makeImportModule } from '../../interop/Module';
|
||||||
|
import { ModuleType } from '../../interop/types';
|
||||||
import { ExportModule, ImportModule } from './types';
|
import { ExportModule, ImportModule } from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,23 +22,23 @@ import { ExportModule, ImportModule } from './types';
|
|||||||
export default class JoplinInterop {
|
export default class JoplinInterop {
|
||||||
|
|
||||||
public async registerExportModule(module: ExportModule) {
|
public async registerExportModule(module: ExportModule) {
|
||||||
const internalModule: Module = {
|
const internalModule = makeExportModule({
|
||||||
...module,
|
...module,
|
||||||
type: ModuleType.Exporter,
|
type: ModuleType.Exporter,
|
||||||
isCustom: true,
|
|
||||||
fileExtensions: module.fileExtensions ? module.fileExtensions : [],
|
fileExtensions: module.fileExtensions ? module.fileExtensions : [],
|
||||||
};
|
}, () => new InteropService_Exporter_Custom(module));
|
||||||
|
|
||||||
return InteropService.instance().registerModule(internalModule);
|
return InteropService.instance().registerModule(internalModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async registerImportModule(module: ImportModule) {
|
public async registerImportModule(module: ImportModule) {
|
||||||
const internalModule: Module = {
|
const internalModule = makeImportModule({
|
||||||
...module,
|
...module,
|
||||||
type: ModuleType.Importer,
|
type: ModuleType.Importer,
|
||||||
isCustom: true,
|
|
||||||
fileExtensions: module.fileExtensions ? module.fileExtensions : [],
|
fileExtensions: module.fileExtensions ? module.fileExtensions : [],
|
||||||
};
|
}, () => {
|
||||||
|
return new InteropService_Importer_Custom(module);
|
||||||
|
});
|
||||||
|
|
||||||
return InteropService.instance().registerModule(internalModule);
|
return InteropService.instance().registerModule(internalModule);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user