1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-08-27 20:29:45 +02:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Laurent Cozic
c239307945 Android release v1.1.2 2020-09-21 13:09:37 +01:00
1359 changed files with 10336 additions and 112882 deletions

View File

@@ -59,54 +59,18 @@ Tools/node_modules
Tools/PortableAppsLauncher
Modules/TinyMCE/IconPack/postinstall.js
Modules/TinyMCE/langs/
CliClient/build/
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
CliClient/app/LinkSelector.js
CliClient/app/services/plugins/PluginRunner.js
CliClient/tests/models_Setting.js
CliClient/tests/services_CommandService.js
CliClient/tests/services_InteropService.js
CliClient/tests/services_PluginService.js
CliClient/tests/services/plugins/sandboxProxy.js
CliClient/tests/support/plugins/codemirror_test/global.d.js
CliClient/tests/support/plugins/codemirror_test/src/index.js
CliClient/tests/support/plugins/dialog/global.d.js
CliClient/tests/support/plugins/dialog/src/index.js
CliClient/tests/support/plugins/events/global.d.js
CliClient/tests/support/plugins/events/src/index.js
CliClient/tests/support/plugins/json_export/global.d.js
CliClient/tests/support/plugins/json_export/src/index.js
CliClient/tests/support/plugins/markdown_plugin/global.d.js
CliClient/tests/support/plugins/markdown_plugin/src/index.js
CliClient/tests/support/plugins/multi_selection/global.d.js
CliClient/tests/support/plugins/multi_selection/src/index.js
CliClient/tests/support/plugins/register_command/global.d.js
CliClient/tests/support/plugins/register_command/src/index.js
CliClient/tests/support/plugins/selected_text/global.d.js
CliClient/tests/support/plugins/selected_text/src/index.js
CliClient/tests/support/plugins/settings/global.d.js
CliClient/tests/support/plugins/settings/src/index.js
CliClient/tests/support/plugins/toc/global.d.js
CliClient/tests/support/plugins/toc/src/index.js
CliClient/tests/support/plugins/withExternalModules/global.d.js
CliClient/tests/support/plugins/withExternalModules/src/index.js
CliClient/build/LinkSelector.js
CliClient/tests/synchronizer_LockHandler.js
CliClient/tests/synchronizer_MigrationHandler.js
ElectronClient/app.js
ElectronClient/bridge.js
ElectronClient/commands/copyDevCommand.js
ElectronClient/commands/focusElement.js
ElectronClient/commands/startExternalEditing.js
ElectronClient/commands/stopExternalEditing.js
ElectronClient/ElectronAppWrapper.js
ElectronClient/global.d.js
ElectronClient/gui/Button/Button.js
ElectronClient/gui/ConfigScreen/ButtonBar.js
ElectronClient/gui/ConfigScreen/ConfigScreen.js
ElectronClient/gui/ConfigScreen/SideBar.js
ElectronClient/gui/DropboxLoginScreen.js
ElectronClient/gui/ErrorBoundary.js
ElectronClient/gui/Header/commands/focusSearch.js
ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js
ElectronClient/gui/KeymapConfig/ShortcutRecorder.js
ElectronClient/gui/KeymapConfig/styles/index.js
@@ -117,8 +81,8 @@ ElectronClient/gui/MainScreen/commands/editAlarm.js
ElectronClient/gui/MainScreen/commands/exportPdf.js
ElectronClient/gui/MainScreen/commands/hideModalMessage.js
ElectronClient/gui/MainScreen/commands/moveToFolder.js
ElectronClient/gui/MainScreen/commands/newFolder.js
ElectronClient/gui/MainScreen/commands/newNote.js
ElectronClient/gui/MainScreen/commands/newNotebook.js
ElectronClient/gui/MainScreen/commands/newTodo.js
ElectronClient/gui/MainScreen/commands/print.js
ElectronClient/gui/MainScreen/commands/renameFolder.js
@@ -130,12 +94,9 @@ ElectronClient/gui/MainScreen/commands/showModalMessage.js
ElectronClient/gui/MainScreen/commands/showNoteContentProperties.js
ElectronClient/gui/MainScreen/commands/showNoteProperties.js
ElectronClient/gui/MainScreen/commands/showShareNoteDialog.js
ElectronClient/gui/MainScreen/commands/toggleEditors.js
ElectronClient/gui/MainScreen/commands/toggleNoteList.js
ElectronClient/gui/MainScreen/commands/toggleSidebar.js
ElectronClient/gui/MainScreen/commands/toggleVisiblePanes.js
ElectronClient/gui/MainScreen/MainScreen.js
ElectronClient/gui/MenuBar.js
ElectronClient/gui/MultiNoteActions.js
ElectronClient/gui/NoteContentPropertiesDialog.js
ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.js
@@ -152,11 +113,9 @@ ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/types.js
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useCursorUtils.js
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useEditorSearch.js
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useJoplinMode.js
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useKeymap.js
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useLineSorting.js
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useListIdent.js
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useScrollUtils.js
ElectronClient/gui/NoteEditor/NoteBody/TinyMCE/styles/index.js
ElectronClient/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.js
ElectronClient/gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.js
ElectronClient/gui/NoteEditor/NoteEditor.js
@@ -166,138 +125,41 @@ ElectronClient/gui/NoteEditor/utils/index.js
ElectronClient/gui/NoteEditor/utils/resourceHandling.js
ElectronClient/gui/NoteEditor/utils/types.js
ElectronClient/gui/NoteEditor/utils/useDropHandler.js
ElectronClient/gui/NoteEditor/utils/useFolder.js
ElectronClient/gui/NoteEditor/utils/useFormNote.js
ElectronClient/gui/NoteEditor/utils/useMarkupToHtml.js
ElectronClient/gui/NoteEditor/utils/useMessageHandler.js
ElectronClient/gui/NoteEditor/utils/useNoteSearchBar.js
ElectronClient/gui/NoteEditor/utils/usePluginServiceRegistration.js
ElectronClient/gui/NoteEditor/utils/useSearchMarkers.js
ElectronClient/gui/NoteEditor/utils/useWindowCommandHandler.js
ElectronClient/gui/NoteList/commands/focusElementNoteList.js
ElectronClient/gui/NoteList/NoteList.js
ElectronClient/gui/NoteListControls/commands/focusSearch.js
ElectronClient/gui/NoteListControls/NoteListControls.js
ElectronClient/gui/NoteListItem.js
ElectronClient/gui/NoteTextViewer.js
ElectronClient/gui/NoteToolbar/NoteToolbar.js
ElectronClient/gui/OneDriveLoginScreen.js
ElectronClient/gui/ResizableLayout/hooks/useLayoutItemSizes.js
ElectronClient/gui/ResizableLayout/hooks/useWindowResizeEvent.js
ElectronClient/gui/ResizableLayout/ResizableLayout.js
ElectronClient/gui/ResourceScreen.js
ElectronClient/gui/Root_UpgradeSyncTarget.js
ElectronClient/gui/Root.js
ElectronClient/gui/SearchBar/hooks/useSearch.js
ElectronClient/gui/SearchBar/SearchBar.js
ElectronClient/gui/SearchBar/styles/index.js
ElectronClient/gui/ShareNoteDialog.js
ElectronClient/gui/SideBar/commands/focusElementSideBar.js
ElectronClient/gui/SideBar/SideBar.js
ElectronClient/gui/SideBar/styles/index.js
ElectronClient/gui/StatusScreen/StatusScreen.js
ElectronClient/gui/style/StyledInput.js
ElectronClient/gui/style/StyledTextInput.js
ElectronClient/gui/ToggleEditorsButton/styles/index.js
ElectronClient/gui/ToggleEditorsButton/ToggleEditorsButton.js
ElectronClient/gui/ToolbarBase.js
ElectronClient/gui/ToolbarButton/styles/index.js
ElectronClient/gui/ToolbarButton/ToolbarButton.js
ElectronClient/gui/utils/NoteListUtils.js
ElectronClient/InteropServiceHelper.js
ElectronClient/services/bridge.js
ElectronClient/services/plugins/hooks/useThemeCss.js
ElectronClient/services/plugins/hooks/useViewIsReady.js
ElectronClient/services/plugins/PlatformImplementation.js
ElectronClient/services/plugins/PluginRunner.js
ElectronClient/services/plugins/UserWebview.js
ElectronClient/services/plugins/UserWebviewDialog.js
ElectronClient/services/plugins/UserWebviewDialogButtonBar.js
ReactNativeClient/lib/AsyncActionQueue.js
ReactNativeClient/lib/BaseApplication.js
ReactNativeClient/lib/checkPermissions.js
ReactNativeClient/lib/commands/historyBackward.js
ReactNativeClient/lib/commands/historyForward.js
ReactNativeClient/lib/commands/synchronize.js
ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js
ReactNativeClient/lib/eventManager.js
ReactNativeClient/lib/hooks/useEffectDebugger.js
ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js
ReactNativeClient/lib/hooks/usePrevious.js
ReactNativeClient/lib/hooks/usePropsDebugger.js
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.js
ReactNativeClient/lib/JoplinServerApi.js
ReactNativeClient/lib/locale.js
ReactNativeClient/lib/Logger.js
ReactNativeClient/lib/models/Alarm.js
ReactNativeClient/lib/models/Setting.js
ReactNativeClient/lib/ntpDate.js
ReactNativeClient/lib/reducer.js
ReactNativeClient/lib/services/AlarmService.js
ReactNativeClient/lib/services/AlarmServiceDriver.android.js
ReactNativeClient/lib/services/AlarmServiceDriver.ios.js
ReactNativeClient/lib/services/AlarmServiceDriverNode.js
ReactNativeClient/lib/services/BaseService.js
ReactNativeClient/lib/services/BooleanExpression.js
ReactNativeClient/lib/services/commands/MenuUtils.js
ReactNativeClient/lib/services/commands/propsHaveChanged.js
ReactNativeClient/lib/services/commands/ToolbarButtonUtils.js
ReactNativeClient/lib/services/CommandService.js
ReactNativeClient/lib/services/contextkey/contextkey.js
ReactNativeClient/lib/services/debug/populateDatabase.js
ReactNativeClient/lib/services/interop/InteropService_Exporter_Base.js
ReactNativeClient/lib/services/interop/InteropService_Exporter_Custom.js
ReactNativeClient/lib/services/interop/InteropService_Exporter_Html.js
ReactNativeClient/lib/services/interop/InteropService_Exporter_Jex.js
ReactNativeClient/lib/services/interop/InteropService_Exporter_Md.js
ReactNativeClient/lib/services/interop/InteropService_Exporter_Raw.js
ReactNativeClient/lib/services/interop/InteropService_Importer_Base.js
ReactNativeClient/lib/services/interop/InteropService_Importer_Custom.js
ReactNativeClient/lib/services/interop/InteropService_Importer_EnexToHtml.js
ReactNativeClient/lib/services/interop/InteropService_Importer_EnexToMd.js
ReactNativeClient/lib/services/interop/InteropService_Importer_Jex.js
ReactNativeClient/lib/services/interop/InteropService_Importer_Md.js
ReactNativeClient/lib/services/interop/InteropService_Importer_Raw.js
ReactNativeClient/lib/services/interop/InteropService.js
ReactNativeClient/lib/services/interop/types.js
ReactNativeClient/lib/services/keychain/KeychainService.js
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.dummy.js
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.mobile.js
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.node.js
ReactNativeClient/lib/services/keychain/KeychainServiceDriverBase.js
ReactNativeClient/lib/services/KeymapService.js
ReactNativeClient/lib/services/plugins/api/Global.js
ReactNativeClient/lib/services/plugins/api/Joplin.js
ReactNativeClient/lib/services/plugins/api/JoplinCommands.js
ReactNativeClient/lib/services/plugins/api/JoplinData.js
ReactNativeClient/lib/services/plugins/api/JoplinFilters.js
ReactNativeClient/lib/services/plugins/api/JoplinInterop.js
ReactNativeClient/lib/services/plugins/api/JoplinPlugins.js
ReactNativeClient/lib/services/plugins/api/JoplinSettings.js
ReactNativeClient/lib/services/plugins/api/JoplinUtils.js
ReactNativeClient/lib/services/plugins/api/JoplinViews.js
ReactNativeClient/lib/services/plugins/api/JoplinViewsDialogs.js
ReactNativeClient/lib/services/plugins/api/JoplinViewsMenuItems.js
ReactNativeClient/lib/services/plugins/api/JoplinViewsPanels.js
ReactNativeClient/lib/services/plugins/api/JoplinViewsToolbarButtons.js
ReactNativeClient/lib/services/plugins/api/JoplinWorkspace.js
ReactNativeClient/lib/services/plugins/BasePluginRunner.js
ReactNativeClient/lib/services/plugins/MenuItemController.js
ReactNativeClient/lib/services/plugins/Plugin.js
ReactNativeClient/lib/services/plugins/PluginService.js
ReactNativeClient/lib/services/plugins/reducer.js
ReactNativeClient/lib/services/plugins/sandboxProxy.js
ReactNativeClient/lib/services/plugins/ToolbarButtonController.js
ReactNativeClient/lib/services/plugins/utils/createViewHandle.js
ReactNativeClient/lib/services/plugins/utils/executeSandboxCall.js
ReactNativeClient/lib/services/plugins/utils/manifestFromObject.js
ReactNativeClient/lib/services/plugins/utils/mapEventHandlersToIds.js
ReactNativeClient/lib/services/plugins/utils/types.js
ReactNativeClient/lib/services/plugins/ViewController.js
ReactNativeClient/lib/services/plugins/WebviewController.js
ReactNativeClient/lib/services/ResourceEditWatcher/index.js
ReactNativeClient/lib/services/ResourceEditWatcher/reducer.js
ReactNativeClient/lib/services/rest/actionApi.desktop.js
@@ -314,19 +176,6 @@ ReactNativeClient/lib/services/synchronizer/utils/types.js
ReactNativeClient/lib/services/UndoRedoService.js
ReactNativeClient/lib/ShareExtension.js
ReactNativeClient/lib/shareHandler.js
ReactNativeClient/lib/shim.js
ReactNativeClient/lib/Synchronizer.js
ReactNativeClient/lib/theme.js
ReactNativeClient/lib/themes/aritimDark.js
ReactNativeClient/lib/themes/dark.js
ReactNativeClient/lib/themes/dracula.js
ReactNativeClient/lib/themes/light.js
ReactNativeClient/lib/themes/nord.js
ReactNativeClient/lib/themes/oledDark.js
ReactNativeClient/lib/themes/solarizedDark.js
ReactNativeClient/lib/themes/solarizedLight.js
ReactNativeClient/lib/themes/type.js
ReactNativeClient/lib/uuid.js
ReactNativeClient/lib/versionInfo.js
ReactNativeClient/PluginAssetsLoader.js
ReactNativeClient/setUpQuickActions.js

View File

@@ -48,9 +48,8 @@ module.exports = {
// -------------------------------
'react/jsx-uses-react': 'error',
'react/jsx-uses-vars': 'error',
'no-unused-vars': ['error', { 'argsIgnorePattern': '^_' }],
'@typescript-eslint/no-unused-vars': ['error', { 'argsIgnorePattern': '^_' }],
'@typescript-eslint/explicit-member-accessibility': 'off',
'no-unused-vars': 'error',
'@typescript-eslint/no-unused-vars': 'error',
'no-constant-condition': 0,
'no-prototype-builtins': 0,
// This error is always a false positive so far since it detects
@@ -122,15 +121,4 @@ module.exports = {
'react-hooks',
'import',
],
'overrides': [
{
// enable the rule specifically for TypeScript files
'files': ['*.ts', '*.tsx'],
'rules': {
// Warn only because it would make it difficult to convert JS classes to TypeScript, unless we
// make everything public which is not great. New code however should specify member accessibility.
'@typescript-eslint/explicit-member-accessibility': ['warn'],
},
},
],
};

157
.gitignore vendored
View File

@@ -52,54 +52,18 @@ Tools/commit_hook.txt
*.map
ReactNativeClient/lib/sql-extensions/spellfix.so
ReactNativeClient/lib/sql-extensions/spellfix.dylib
CliClient/build/
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
CliClient/app/LinkSelector.js
CliClient/app/services/plugins/PluginRunner.js
CliClient/tests/models_Setting.js
CliClient/tests/services_CommandService.js
CliClient/tests/services_InteropService.js
CliClient/tests/services_PluginService.js
CliClient/tests/services/plugins/sandboxProxy.js
CliClient/tests/support/plugins/codemirror_test/global.d.js
CliClient/tests/support/plugins/codemirror_test/src/index.js
CliClient/tests/support/plugins/dialog/global.d.js
CliClient/tests/support/plugins/dialog/src/index.js
CliClient/tests/support/plugins/events/global.d.js
CliClient/tests/support/plugins/events/src/index.js
CliClient/tests/support/plugins/json_export/global.d.js
CliClient/tests/support/plugins/json_export/src/index.js
CliClient/tests/support/plugins/markdown_plugin/global.d.js
CliClient/tests/support/plugins/markdown_plugin/src/index.js
CliClient/tests/support/plugins/multi_selection/global.d.js
CliClient/tests/support/plugins/multi_selection/src/index.js
CliClient/tests/support/plugins/register_command/global.d.js
CliClient/tests/support/plugins/register_command/src/index.js
CliClient/tests/support/plugins/selected_text/global.d.js
CliClient/tests/support/plugins/selected_text/src/index.js
CliClient/tests/support/plugins/settings/global.d.js
CliClient/tests/support/plugins/settings/src/index.js
CliClient/tests/support/plugins/toc/global.d.js
CliClient/tests/support/plugins/toc/src/index.js
CliClient/tests/support/plugins/withExternalModules/global.d.js
CliClient/tests/support/plugins/withExternalModules/src/index.js
CliClient/build/LinkSelector.js
CliClient/tests/synchronizer_LockHandler.js
CliClient/tests/synchronizer_MigrationHandler.js
ElectronClient/app.js
ElectronClient/bridge.js
ElectronClient/commands/copyDevCommand.js
ElectronClient/commands/focusElement.js
ElectronClient/commands/startExternalEditing.js
ElectronClient/commands/stopExternalEditing.js
ElectronClient/ElectronAppWrapper.js
ElectronClient/global.d.js
ElectronClient/gui/Button/Button.js
ElectronClient/gui/ConfigScreen/ButtonBar.js
ElectronClient/gui/ConfigScreen/ConfigScreen.js
ElectronClient/gui/ConfigScreen/SideBar.js
ElectronClient/gui/DropboxLoginScreen.js
ElectronClient/gui/ErrorBoundary.js
ElectronClient/gui/Header/commands/focusSearch.js
ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js
ElectronClient/gui/KeymapConfig/ShortcutRecorder.js
ElectronClient/gui/KeymapConfig/styles/index.js
@@ -110,8 +74,8 @@ ElectronClient/gui/MainScreen/commands/editAlarm.js
ElectronClient/gui/MainScreen/commands/exportPdf.js
ElectronClient/gui/MainScreen/commands/hideModalMessage.js
ElectronClient/gui/MainScreen/commands/moveToFolder.js
ElectronClient/gui/MainScreen/commands/newFolder.js
ElectronClient/gui/MainScreen/commands/newNote.js
ElectronClient/gui/MainScreen/commands/newNotebook.js
ElectronClient/gui/MainScreen/commands/newTodo.js
ElectronClient/gui/MainScreen/commands/print.js
ElectronClient/gui/MainScreen/commands/renameFolder.js
@@ -123,12 +87,9 @@ ElectronClient/gui/MainScreen/commands/showModalMessage.js
ElectronClient/gui/MainScreen/commands/showNoteContentProperties.js
ElectronClient/gui/MainScreen/commands/showNoteProperties.js
ElectronClient/gui/MainScreen/commands/showShareNoteDialog.js
ElectronClient/gui/MainScreen/commands/toggleEditors.js
ElectronClient/gui/MainScreen/commands/toggleNoteList.js
ElectronClient/gui/MainScreen/commands/toggleSidebar.js
ElectronClient/gui/MainScreen/commands/toggleVisiblePanes.js
ElectronClient/gui/MainScreen/MainScreen.js
ElectronClient/gui/MenuBar.js
ElectronClient/gui/MultiNoteActions.js
ElectronClient/gui/NoteContentPropertiesDialog.js
ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.js
@@ -145,11 +106,9 @@ ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/types.js
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useCursorUtils.js
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useEditorSearch.js
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useJoplinMode.js
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useKeymap.js
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useLineSorting.js
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useListIdent.js
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useScrollUtils.js
ElectronClient/gui/NoteEditor/NoteBody/TinyMCE/styles/index.js
ElectronClient/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.js
ElectronClient/gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.js
ElectronClient/gui/NoteEditor/NoteEditor.js
@@ -159,138 +118,41 @@ ElectronClient/gui/NoteEditor/utils/index.js
ElectronClient/gui/NoteEditor/utils/resourceHandling.js
ElectronClient/gui/NoteEditor/utils/types.js
ElectronClient/gui/NoteEditor/utils/useDropHandler.js
ElectronClient/gui/NoteEditor/utils/useFolder.js
ElectronClient/gui/NoteEditor/utils/useFormNote.js
ElectronClient/gui/NoteEditor/utils/useMarkupToHtml.js
ElectronClient/gui/NoteEditor/utils/useMessageHandler.js
ElectronClient/gui/NoteEditor/utils/useNoteSearchBar.js
ElectronClient/gui/NoteEditor/utils/usePluginServiceRegistration.js
ElectronClient/gui/NoteEditor/utils/useSearchMarkers.js
ElectronClient/gui/NoteEditor/utils/useWindowCommandHandler.js
ElectronClient/gui/NoteList/commands/focusElementNoteList.js
ElectronClient/gui/NoteList/NoteList.js
ElectronClient/gui/NoteListControls/commands/focusSearch.js
ElectronClient/gui/NoteListControls/NoteListControls.js
ElectronClient/gui/NoteListItem.js
ElectronClient/gui/NoteTextViewer.js
ElectronClient/gui/NoteToolbar/NoteToolbar.js
ElectronClient/gui/OneDriveLoginScreen.js
ElectronClient/gui/ResizableLayout/hooks/useLayoutItemSizes.js
ElectronClient/gui/ResizableLayout/hooks/useWindowResizeEvent.js
ElectronClient/gui/ResizableLayout/ResizableLayout.js
ElectronClient/gui/ResourceScreen.js
ElectronClient/gui/Root_UpgradeSyncTarget.js
ElectronClient/gui/Root.js
ElectronClient/gui/SearchBar/hooks/useSearch.js
ElectronClient/gui/SearchBar/SearchBar.js
ElectronClient/gui/SearchBar/styles/index.js
ElectronClient/gui/ShareNoteDialog.js
ElectronClient/gui/SideBar/commands/focusElementSideBar.js
ElectronClient/gui/SideBar/SideBar.js
ElectronClient/gui/SideBar/styles/index.js
ElectronClient/gui/StatusScreen/StatusScreen.js
ElectronClient/gui/style/StyledInput.js
ElectronClient/gui/style/StyledTextInput.js
ElectronClient/gui/ToggleEditorsButton/styles/index.js
ElectronClient/gui/ToggleEditorsButton/ToggleEditorsButton.js
ElectronClient/gui/ToolbarBase.js
ElectronClient/gui/ToolbarButton/styles/index.js
ElectronClient/gui/ToolbarButton/ToolbarButton.js
ElectronClient/gui/utils/NoteListUtils.js
ElectronClient/InteropServiceHelper.js
ElectronClient/services/bridge.js
ElectronClient/services/plugins/hooks/useThemeCss.js
ElectronClient/services/plugins/hooks/useViewIsReady.js
ElectronClient/services/plugins/PlatformImplementation.js
ElectronClient/services/plugins/PluginRunner.js
ElectronClient/services/plugins/UserWebview.js
ElectronClient/services/plugins/UserWebviewDialog.js
ElectronClient/services/plugins/UserWebviewDialogButtonBar.js
ReactNativeClient/lib/AsyncActionQueue.js
ReactNativeClient/lib/BaseApplication.js
ReactNativeClient/lib/checkPermissions.js
ReactNativeClient/lib/commands/historyBackward.js
ReactNativeClient/lib/commands/historyForward.js
ReactNativeClient/lib/commands/synchronize.js
ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js
ReactNativeClient/lib/eventManager.js
ReactNativeClient/lib/hooks/useEffectDebugger.js
ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js
ReactNativeClient/lib/hooks/usePrevious.js
ReactNativeClient/lib/hooks/usePropsDebugger.js
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.js
ReactNativeClient/lib/JoplinServerApi.js
ReactNativeClient/lib/locale.js
ReactNativeClient/lib/Logger.js
ReactNativeClient/lib/models/Alarm.js
ReactNativeClient/lib/models/Setting.js
ReactNativeClient/lib/ntpDate.js
ReactNativeClient/lib/reducer.js
ReactNativeClient/lib/services/AlarmService.js
ReactNativeClient/lib/services/AlarmServiceDriver.android.js
ReactNativeClient/lib/services/AlarmServiceDriver.ios.js
ReactNativeClient/lib/services/AlarmServiceDriverNode.js
ReactNativeClient/lib/services/BaseService.js
ReactNativeClient/lib/services/BooleanExpression.js
ReactNativeClient/lib/services/commands/MenuUtils.js
ReactNativeClient/lib/services/commands/propsHaveChanged.js
ReactNativeClient/lib/services/commands/ToolbarButtonUtils.js
ReactNativeClient/lib/services/CommandService.js
ReactNativeClient/lib/services/contextkey/contextkey.js
ReactNativeClient/lib/services/debug/populateDatabase.js
ReactNativeClient/lib/services/interop/InteropService_Exporter_Base.js
ReactNativeClient/lib/services/interop/InteropService_Exporter_Custom.js
ReactNativeClient/lib/services/interop/InteropService_Exporter_Html.js
ReactNativeClient/lib/services/interop/InteropService_Exporter_Jex.js
ReactNativeClient/lib/services/interop/InteropService_Exporter_Md.js
ReactNativeClient/lib/services/interop/InteropService_Exporter_Raw.js
ReactNativeClient/lib/services/interop/InteropService_Importer_Base.js
ReactNativeClient/lib/services/interop/InteropService_Importer_Custom.js
ReactNativeClient/lib/services/interop/InteropService_Importer_EnexToHtml.js
ReactNativeClient/lib/services/interop/InteropService_Importer_EnexToMd.js
ReactNativeClient/lib/services/interop/InteropService_Importer_Jex.js
ReactNativeClient/lib/services/interop/InteropService_Importer_Md.js
ReactNativeClient/lib/services/interop/InteropService_Importer_Raw.js
ReactNativeClient/lib/services/interop/InteropService.js
ReactNativeClient/lib/services/interop/types.js
ReactNativeClient/lib/services/keychain/KeychainService.js
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.dummy.js
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.mobile.js
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.node.js
ReactNativeClient/lib/services/keychain/KeychainServiceDriverBase.js
ReactNativeClient/lib/services/KeymapService.js
ReactNativeClient/lib/services/plugins/api/Global.js
ReactNativeClient/lib/services/plugins/api/Joplin.js
ReactNativeClient/lib/services/plugins/api/JoplinCommands.js
ReactNativeClient/lib/services/plugins/api/JoplinData.js
ReactNativeClient/lib/services/plugins/api/JoplinFilters.js
ReactNativeClient/lib/services/plugins/api/JoplinInterop.js
ReactNativeClient/lib/services/plugins/api/JoplinPlugins.js
ReactNativeClient/lib/services/plugins/api/JoplinSettings.js
ReactNativeClient/lib/services/plugins/api/JoplinUtils.js
ReactNativeClient/lib/services/plugins/api/JoplinViews.js
ReactNativeClient/lib/services/plugins/api/JoplinViewsDialogs.js
ReactNativeClient/lib/services/plugins/api/JoplinViewsMenuItems.js
ReactNativeClient/lib/services/plugins/api/JoplinViewsPanels.js
ReactNativeClient/lib/services/plugins/api/JoplinViewsToolbarButtons.js
ReactNativeClient/lib/services/plugins/api/JoplinWorkspace.js
ReactNativeClient/lib/services/plugins/BasePluginRunner.js
ReactNativeClient/lib/services/plugins/MenuItemController.js
ReactNativeClient/lib/services/plugins/Plugin.js
ReactNativeClient/lib/services/plugins/PluginService.js
ReactNativeClient/lib/services/plugins/reducer.js
ReactNativeClient/lib/services/plugins/sandboxProxy.js
ReactNativeClient/lib/services/plugins/ToolbarButtonController.js
ReactNativeClient/lib/services/plugins/utils/createViewHandle.js
ReactNativeClient/lib/services/plugins/utils/executeSandboxCall.js
ReactNativeClient/lib/services/plugins/utils/manifestFromObject.js
ReactNativeClient/lib/services/plugins/utils/mapEventHandlersToIds.js
ReactNativeClient/lib/services/plugins/utils/types.js
ReactNativeClient/lib/services/plugins/ViewController.js
ReactNativeClient/lib/services/plugins/WebviewController.js
ReactNativeClient/lib/services/ResourceEditWatcher/index.js
ReactNativeClient/lib/services/ResourceEditWatcher/reducer.js
ReactNativeClient/lib/services/rest/actionApi.desktop.js
@@ -307,19 +169,6 @@ ReactNativeClient/lib/services/synchronizer/utils/types.js
ReactNativeClient/lib/services/UndoRedoService.js
ReactNativeClient/lib/ShareExtension.js
ReactNativeClient/lib/shareHandler.js
ReactNativeClient/lib/shim.js
ReactNativeClient/lib/Synchronizer.js
ReactNativeClient/lib/theme.js
ReactNativeClient/lib/themes/aritimDark.js
ReactNativeClient/lib/themes/dark.js
ReactNativeClient/lib/themes/dracula.js
ReactNativeClient/lib/themes/light.js
ReactNativeClient/lib/themes/nord.js
ReactNativeClient/lib/themes/oledDark.js
ReactNativeClient/lib/themes/solarizedDark.js
ReactNativeClient/lib/themes/solarizedLight.js
ReactNativeClient/lib/themes/type.js
ReactNativeClient/lib/uuid.js
ReactNativeClient/lib/versionInfo.js
ReactNativeClient/PluginAssetsLoader.js
ReactNativeClient/setUpQuickActions.js

View File

@@ -11,7 +11,6 @@ Note that all the applications share the same library, which, for historical rea
- macOS, Linux: Install rsync - https://nodejs.org/en/
- macOS: Install Cocoapods - `brew install cocoapods`
- Windows: Install Windows Build Tools - `npm install -g windows-build-tools`
- Linux: Install dependencies - `sudo apt install libnss3 libsecret-1-dev`
## Building
@@ -26,8 +25,6 @@ Then you can test the various applications:
cd ElectronClient
npm start
You can also run it under WSL 2. To do so, [follow these instructions](https://www.beekeeperstudio.io/blog/building-electron-windows-ubuntu-wsl2) to setup your environment.
## Testing the Terminal application
cd CliClient

View File

@@ -1,4 +1,4 @@
const Logger = require('lib/Logger').default;
const { Logger } = require('lib/logger.js');
const { netUtils } = require('lib/net-utils.js');
const http = require('http');

View File

@@ -1,17 +1,15 @@
const Logger = require('lib/Logger').default;
const { Logger } = require('lib/logger.js');
const Folder = require('lib/models/Folder.js');
const BaseItem = require('lib/models/BaseItem.js');
const Tag = require('lib/models/Tag.js');
const BaseModel = require('lib/BaseModel.js');
const Note = require('lib/models/Note.js');
const Resource = require('lib/models/Resource.js');
const Setting = require('lib/models/Setting').default;
const reducer = require('lib/reducer').default;
const { defaultState } = require('lib/reducer');
const Setting = require('lib/models/Setting.js');
const { reducer, defaultState } = require('lib/reducer.js');
const { splitCommandString } = require('lib/string-utils.js');
const { reg } = require('lib/registry.js');
const { _ } = require('lib/locale');
const shim = require('lib/shim').default;
const { _ } = require('lib/locale.js');
const Entities = require('html-entities').AllHtmlEntities;
const htmlentities = new Entities().encode;
@@ -479,7 +477,7 @@ class AppGui {
this.linkSelector_.noteX + cursorOffsetX,
this.linkSelector_.noteY + cursorOffsetY
);
shim.setTimeout(() => this.term_.term().inverse(this.linkSelector_.link), 50);
setTimeout(() => this.term_.term().inverse(this.linkSelector_.link), 50);
}
} else if (cmd === 'open_link') {
if (this.widget('noteText').hasFocus) {

View File

@@ -1,4 +1,4 @@
const BaseApplication = require('lib/BaseApplication').default;
const { BaseApplication } = require('lib/BaseApplication');
const { FoldersScreenUtils } = require('lib/folders-screen-utils.js');
const ResourceService = require('lib/services/ResourceService');
const BaseModel = require('lib/BaseModel.js');
@@ -6,15 +6,14 @@ const Folder = require('lib/models/Folder.js');
const BaseItem = require('lib/models/BaseItem.js');
const Note = require('lib/models/Note.js');
const Tag = require('lib/models/Tag.js');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
const { reg } = require('lib/registry.js');
const { fileExtension } = require('lib/path-utils.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const fs = require('fs-extra');
const { cliUtils } = require('./cli-utils.js');
const Cache = require('lib/Cache');
const RevisionService = require('lib/services/RevisionService');
const shim = require('lib/shim').default;
class Application extends BaseApplication {
constructor() {
@@ -162,7 +161,7 @@ class Application extends BaseApplication {
};
// Give it a few seconds to cancel otherwise exit anyway
shim.setTimeout(async () => {
setTimeout(async () => {
await doExit();
}, 5000);

View File

@@ -1,4 +1,4 @@
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const { reg } = require('lib/registry.js');
class BaseCommand {

View File

@@ -1,7 +1,7 @@
const fs = require('fs-extra');
const { fileExtension, dirname } = require('lib/path-utils.js');
const wrap_ = require('word-wrap');
const { languageCode } = require('lib/locale');
const { languageCode } = require('lib/locale.js');
const rootDir = dirname(dirname(__dirname));
const MAX_WIDTH = 78;

View File

@@ -1,14 +1,14 @@
'use strict';
const fs = require('fs-extra');
const Logger = require('lib/Logger').default;
const { Logger } = require('lib/logger.js');
const { dirname } = require('lib/path-utils.js');
const { DatabaseDriverNode } = require('lib/database-driver-node.js');
const { JoplinDatabase } = require('lib/joplin-database.js');
const BaseModel = require('lib/BaseModel.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
const { sprintf } = require('sprintf-js');
const exec = require('child_process').exec;

View File

@@ -1,8 +1,8 @@
const yargParser = require('yargs-parser');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const { time } = require('lib/time-utils.js');
const stringPadding = require('string-padding');
const Logger = require('lib/Logger').default;
const { Logger } = require('lib/logger.js');
const cliUtils = {};

View File

@@ -1,8 +1,8 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const BaseModel = require('lib/BaseModel.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim.js');
class Command extends BaseCommand {
usage() {

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const BaseModel = require('lib/BaseModel.js');
const BaseItem = require('lib/models/BaseItem.js');
const Note = require('lib/models/Note.js');

View File

@@ -1,8 +1,8 @@
const { BaseCommand } = require('./base-command.js');
const { _, setLocale } = require('lib/locale');
const { _, setLocale } = require('lib/locale.js');
const { app } = require('./app.js');
const fs = require('fs-extra');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
class Command extends BaseCommand {
usage() {

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const BaseModel = require('lib/BaseModel.js');
const Note = require('lib/models/Note.js');

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const BaseModel = require('lib/BaseModel.js');
const Note = require('lib/models/Note.js');
const { time } = require('lib/time-utils.js');

View File

@@ -1,10 +1,10 @@
const { BaseCommand } = require('./base-command.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const EncryptionService = require('lib/services/EncryptionService');
const DecryptionWorker = require('lib/services/DecryptionWorker');
const BaseItem = require('lib/models/BaseItem');
const Setting = require('lib/models/Setting').default;
const shim = require('lib/shim').default;
const Setting = require('lib/models/Setting.js');
const { shim } = require('lib/shim');
const pathUtils = require('lib/path-utils.js');
const imageType = require('image-type');
const readChunk = require('read-chunk');
@@ -38,7 +38,7 @@ class Command extends BaseCommand {
this.stdout(_('Operation cancelled'));
return false;
}
Setting.setObjectValue('encryption.passwordCache', masterKeyId, password);
Setting.setObjectKey('encryption.passwordCache', masterKeyId, password);
await EncryptionService.instance().loadMasterKeysFromSettings();
return true;
};

View File

@@ -1,11 +1,11 @@
const fs = require('fs-extra');
const { BaseCommand } = require('./base-command.js');
const { splitCommandString } = require('lib/string-utils.js');
const uuid = require('lib/uuid').default;
const { uuid } = require('lib/uuid.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const Note = require('lib/models/Note.js');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
const BaseModel = require('lib/BaseModel.js');
class Command extends BaseCommand {

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
class Command extends BaseCommand {
usage() {

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
const { ReportService } = require('lib/services/report.js');
const fs = require('fs-extra');

View File

@@ -1,8 +1,8 @@
const { BaseCommand } = require('./base-command.js');
const InteropService = require('lib/services/interop/InteropService').default;
const InteropService = require('lib/services/InteropService.js');
const BaseModel = require('lib/BaseModel.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
class Command extends BaseCommand {
usage() {
@@ -14,7 +14,7 @@ class Command extends BaseCommand {
}
options() {
const service = InteropService.instance();
const service = new InteropService();
const formats = service
.modules()
.filter(m => m.type === 'exporter' && m.format !== 'html')
@@ -41,7 +41,7 @@ class Command extends BaseCommand {
exportOptions.sourceFolderIds = folders.map(n => n.id);
}
const service = InteropService.instance();
const service = new InteropService();
const result = await service.export(exportOptions);
result.warnings.map(w => this.stdout(w));

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const BaseModel = require('lib/BaseModel.js');
const Note = require('lib/models/Note.js');

View File

@@ -1,7 +1,7 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { renderCommandHelp } = require('./help-utils.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const { cliUtils } = require('./cli-utils.js');
class Command extends BaseCommand {

View File

@@ -1,9 +1,9 @@
const { BaseCommand } = require('./base-command.js');
const InteropService = require('lib/services/interop/InteropService').default;
const InteropService = require('lib/services/InteropService.js');
const BaseModel = require('lib/BaseModel.js');
const { cliUtils } = require('./cli-utils.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
class Command extends BaseCommand {
usage() {
@@ -15,7 +15,7 @@ class Command extends BaseCommand {
}
options() {
const service = InteropService.instance();
const service = new InteropService();
const formats = service
.modules()
.filter(m => m.type === 'importer')
@@ -63,7 +63,7 @@ class Command extends BaseCommand {
app().gui().showConsole();
this.stdout(_('Importing notes...'));
const service = InteropService.instance();
const service = new InteropService();
const result = await service.import(importOptions);
result.warnings.map(w => this.stdout(w));
cliUtils.redrawDone();

View File

@@ -1,9 +1,9 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const BaseModel = require('lib/BaseModel.js');
const Folder = require('lib/models/Folder.js');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
const Note = require('lib/models/Note.js');
const { sprintf } = require('sprintf-js');
const { time } = require('lib/time-utils.js');

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const Folder = require('lib/models/Folder.js');
class Command extends BaseCommand {

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const Note = require('lib/models/Note.js');
class Command extends BaseCommand {

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const Note = require('lib/models/Note.js');
class Command extends BaseCommand {

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const BaseModel = require('lib/BaseModel.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const BaseModel = require('lib/BaseModel.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const Folder = require('lib/models/Folder.js');
const BaseModel = require('lib/BaseModel.js');

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const Note = require('lib/models/Note.js');
const BaseModel = require('lib/BaseModel.js');

View File

@@ -1,8 +1,8 @@
const { BaseCommand } = require('./base-command.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const BaseModel = require('lib/BaseModel.js');
const Folder = require('lib/models/Folder.js');
const uuid = require('lib/uuid').default;
const { uuid } = require('lib/uuid.js');
class Command extends BaseCommand {
usage() {

View File

@@ -1,8 +1,8 @@
const { BaseCommand } = require('./base-command.js');
const { _ } = require('lib/locale');
const Setting = require('lib/models/Setting').default;
const Logger = require('lib/Logger').default;
const shim = require('lib/shim').default;
const { _ } = require('lib/locale.js');
const Setting = require('lib/models/Setting.js');
const { Logger } = require('lib/logger.js');
const { shim } = require('lib/shim');
class Command extends BaseCommand {

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const BaseModel = require('lib/BaseModel.js');
const { Database } = require('lib/database.js');
const Note = require('lib/models/Note.js');

View File

@@ -1,7 +1,7 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const Setting = require('lib/models/Setting').default;
const { _ } = require('lib/locale');
const Setting = require('lib/models/Setting.js');
const { _ } = require('lib/locale.js');
const { ReportService } = require('lib/services/report.js');
class Command extends BaseCommand {

View File

@@ -1,10 +1,10 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const { OneDriveApiNodeUtils } = require('lib/onedrive-api-node-utils.js');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
const ResourceFetcher = require('lib/services/ResourceFetcher');
const Synchronizer = require('lib/Synchronizer').default;
const { Synchronizer } = require('lib/synchronizer.js');
const { reg } = require('lib/registry.js');
const { cliUtils } = require('./cli-utils.js');
const md5 = require('md5');

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const Tag = require('lib/models/Tag.js');
const BaseModel = require('lib/BaseModel.js');
const { time } = require('lib/time-utils.js');

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const BaseModel = require('lib/BaseModel.js');
const Note = require('lib/models/Note.js');
const { time } = require('lib/time-utils.js');

View File

@@ -1,5 +1,5 @@
const { BaseCommand } = require('./base-command.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const CommandDone = require('./command-done.js');

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const BaseModel = require('lib/BaseModel.js');
class Command extends BaseCommand {

View File

@@ -1,6 +1,6 @@
const { BaseCommand } = require('./base-command.js');
const Setting = require('lib/models/Setting').default;
const { _ } = require('lib/locale');
const Setting = require('lib/models/Setting.js');
const { _ } = require('lib/locale.js');
class Command extends BaseCommand {
usage() {

View File

@@ -1,7 +1,7 @@
'use strict';
const { time } = require('lib/time-utils.js');
const Logger = require('lib/Logger').default;
const { Logger } = require('lib/logger.js');
const Resource = require('lib/models/Resource.js');
const { dirname } = require('lib/path-utils.js');
const { FsDriverNode } = require('./fs-driver-node.js');

View File

@@ -2,7 +2,7 @@ const Folder = require('lib/models/Folder.js');
const Tag = require('lib/models/Tag.js');
const BaseModel = require('lib/BaseModel.js');
const ListWidget = require('tkwidgets/ListWidget.js');
const _ = require('lib/locale')._;
const _ = require('lib/locale.js')._;
class FolderListWidget extends ListWidget {
constructor() {

View File

@@ -1,6 +1,6 @@
const Note = require('lib/models/Note.js');
const TextWidget = require('tkwidgets/TextWidget.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
class NoteWidget extends TextWidget {
constructor() {

View File

@@ -1,6 +1,6 @@
const { wrap } = require('lib/string-utils.js');
const Setting = require('lib/models/Setting').default;
const { _ } = require('lib/locale');
const Setting = require('lib/models/Setting.js');
const { _ } = require('lib/locale.js');
const MAX_WIDTH = 78;
const INDENT = ' ';

View File

@@ -21,12 +21,12 @@ const Note = require('lib/models/Note.js');
const Tag = require('lib/models/Tag.js');
const NoteTag = require('lib/models/NoteTag.js');
const MasterKey = require('lib/models/MasterKey');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
const Revision = require('lib/models/Revision.js');
const Logger = require('lib/Logger').default;
const { Logger } = require('lib/logger.js');
const { FsDriverNode } = require('lib/fs-driver-node.js');
const { shimInit } = require('lib/shim-init-node.js');
const { _ } = require('lib/locale');
const { _ } = require('lib/locale.js');
const { FileApiDriverLocal } = require('lib/file-api-driver-local.js');
const EncryptionService = require('lib/services/EncryptionService');
const envFromArgs = require('lib/envFromArgs');

View File

@@ -1,68 +0,0 @@
import * as vm from 'vm';
import Plugin from 'lib/services/plugins/Plugin';
import sandboxProxy from 'lib/services/plugins/sandboxProxy';
import BasePluginRunner from 'lib/services/plugins/BasePluginRunner';
import executeSandboxCall from 'lib/services/plugins/utils/executeSandboxCall';
import Global from 'lib/services/plugins/api/Global';
import mapEventHandlersToIds, { EventHandlers } from 'lib/services/plugins/utils/mapEventHandlersToIds';
function createConsoleWrapper(pluginId:string) {
const wrapper:any = {};
for (const n in console) {
if (!console.hasOwnProperty(n)) continue;
wrapper[n] = (...args:any[]) => {
const newArgs = args.slice();
newArgs.splice(0, 0, `Plugin "${pluginId}":`);
return (console as any)[n](...newArgs);
};
}
return wrapper;
}
// The CLI plugin runner is more complex than it needs to be because it more or less emulates
// how it would work in a multi-process architecture, as in the desktop app (and probably how
// it would work in the mobile app too). This is mainly to allow doing integration testing.
//
// For example, all plugin calls go through a proxy, however they could made directly since
// the plugin script is running within the same process as the main app.
export default class PluginRunner extends BasePluginRunner {
private eventHandlers_:EventHandlers = {};
constructor() {
super();
this.eventHandler = this.eventHandler.bind(this);
}
private async eventHandler(eventHandlerId:string, args:any[]) {
const cb = this.eventHandlers_[eventHandlerId];
return cb(...args);
}
private newSandboxProxy(pluginId:string, sandbox:Global) {
const target = async (path:string, args:any[]) => {
return executeSandboxCall(pluginId, sandbox, `joplin.${path}`, mapEventHandlersToIds(args, this.eventHandlers_), this.eventHandler);
};
return {
joplin: sandboxProxy(target),
console: createConsoleWrapper(pluginId),
};
}
async run(plugin:Plugin, sandbox:Global) {
const vmSandbox = vm.createContext(this.newSandboxProxy(plugin.id, sandbox));
try {
vm.runInContext(plugin.scriptText, vmSandbox);
} catch (error) {
this.logger().error(`In plugin ${plugin.id}:`, error);
return;
}
}
}

View File

@@ -46,14 +46,8 @@ tasks.prepareTestBuild = {
],
});
const rootDir = utils.rootDir();
await utils.copyDir(`${rootDir}/ReactNativeClient/lib`, `${testBuildDir}/lib`, {
excluded: [
`${rootDir}/ReactNativeClient/lib/joplin-renderer/node_modules`,
],
});
await utils.copyDir(`${rootDir}/ReactNativeClient/locales`, `${testBuildDir}/locales`);
await utils.copyDir(`${__dirname}/../ReactNativeClient/lib`, `${testBuildDir}/lib`);
await utils.copyDir(`${__dirname}/../ReactNativeClient/locales`, `${testBuildDir}/locales`);
await fs.mkdirp(`${testBuildDir}/data`);
},
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.4.1\n"
"X-Generator: Poedit 2.0.6\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
@@ -822,8 +822,8 @@ msgid ""
"Type a note title or part of its content to jump to it. Or type # followed "
"by a tag name, or @ followed by a notebook name."
msgstr ""
"Entrez le titre d’une note, ou entrez # suivi du nom d’une étiquette, ou @ "
"suivi du nom d’un carnet."
"Entrez le titre d’une note, ou entrez # suivit du nom d’une étiquette, ou @ "
"suivit du nom d’un carnet."
#: ElectronClient/plugins/GotoAnything.min.js:486
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:20

View File

@@ -15,8 +15,6 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.4\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
#: CliClient/app/command-cp.js:13
msgid ""
@@ -314,7 +312,7 @@ msgstr "指定のターゲットと同期します。(標準: sync.targetの
#: CliClient/app/command-sync.js:35
msgid "Upgrade the sync target to the latest version."
msgstr "同期先を最新バージョンにアップグレード。"
msgstr ""
#: CliClient/app/command-sync.js:81 CliClient/app/command-sync.js:95
#: ElectronClient/gui/OneDriveLoginScreen.min.js:40
@@ -798,8 +796,6 @@ msgstr "キャンセル"
msgid ""
"The app is now going to close. Please relaunch it to complete the process."
msgstr ""
"まもなくアプリケーションは終了します。もう一度起動して処理を完了させてくださ"
"い。"
#: ElectronClient/plugins/GotoAnything.min.js:446
msgid ""
@@ -1161,13 +1157,13 @@ msgstr "新しい %s を作成中..."
#: ElectronClient/gui/NoteEditor/NoteEditor.js:344
msgid "The following attachments are being watched for changes:"
msgstr "下記の添付ファイルが変更されたかどうかを監視中です。"
msgstr ""
#: ElectronClient/gui/NoteEditor/NoteEditor.js:347
msgid ""
"The attachments will no longer be watched when you switch to a different "
"note."
msgstr "添付ファイルの監視は他のノートに移動すると終了します。"
msgstr ""
#: ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.js:25
msgid "Select all"
@@ -1278,7 +1274,7 @@ msgstr "ノートのプロパティ"
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:62
msgid "An unexpected error occured while importing the keymap!"
msgstr "キーマップのインポート中に予期しないエラーが発生しました!"
msgstr ""
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:119
#: ElectronClient/gui/MainScreen/MainScreen.min.js:437
@@ -1293,11 +1289,12 @@ msgstr "インポート"
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:125
msgid "Command"
msgstr "コマンド"
msgstr ""
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:126
#, fuzzy
msgid "Keyboard Shortcut"
msgstr "ショートカットキー"
msgstr "キーバインド"
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:14
#: ElectronClient/app.js:690
@@ -1320,8 +1317,9 @@ msgid "Website and documentation"
msgstr "Webサイトとドキュメント"
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:24
#, fuzzy
msgid "Hide Joplin"
msgstr "Joplinを隠す"
msgstr "Joplinについて"
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:26
#: ElectronClient/app.js:703
@@ -1329,6 +1327,7 @@ msgid "Close Window"
msgstr "ウィンドウを閉じる"
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:28
#, fuzzy
msgid "Preferences"
msgstr "環境設定"
@@ -1339,15 +1338,13 @@ msgstr "オプション"
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:48
msgid "Press the shortcut"
msgstr "ショートカットキーを押してください"
msgstr ""
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:48
msgid ""
"Press the shortcut and then press ENTER. Or, press BACKSPACE to clear the "
"shortcut."
msgstr ""
"ショートカットキーに続けてENTERを押すことで設定します。ショートカットを削除す"
"るにはBACKSPACEを押してください。"
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:49
#: ElectronClient/gui/EncryptionConfigScreen.min.js:95
@@ -1361,13 +1358,11 @@ msgid ""
"may take a few minutes to complete and the app needs to be restarted. To "
"proceed please click on the link."
msgstr ""
"同期するには同期先をアップグレードする必要があります。アップグレードには数分"
"かかるかもしれません。またアプリケーションの再起動が必要です。アップグレード"
"するにはリンクをクリックしてください。"
#: ElectronClient/gui/MainScreen/MainScreen.min.js:306
#, fuzzy
msgid "Restart and upgrade"
msgstr "再起動してアップグレード"
msgstr "アップグレードが必要なマスターキー"
#: ElectronClient/gui/MainScreen/MainScreen.min.js:313
msgid "Some items cannot be synchronised."
@@ -2119,8 +2114,9 @@ msgid "Templates"
msgstr "テンプレート"
#: ElectronClient/app.js:668
#, fuzzy
msgid "Export all"
msgstr "すべてをエクスポート"
msgstr "エクスポート"
#: ElectronClient/app.js:683
#, javascript-format
@@ -2219,7 +2215,7 @@ msgstr "不明なレベルID: %s"
#: ReactNativeClient/lib/SyncTargetAmazonS3.js:28
msgid "AWS S3"
msgstr "AWS S3"
msgstr ""
#: ReactNativeClient/lib/SyncTargetDropbox.js:25
msgid "Dropbox"
@@ -2364,15 +2360,15 @@ msgstr "WevDAV パスワード"
#: ReactNativeClient/lib/models/Setting.js:195
msgid "AWS S3 bucket"
msgstr "AWS S3 バケット"
msgstr ""
#: ReactNativeClient/lib/models/Setting.js:206
msgid "AWS key"
msgstr "AWS アクセスキーID"
msgstr ""
#: ReactNativeClient/lib/models/Setting.js:216
msgid "AWS secret"
msgstr "AWS シークレットアクセスキー"
msgstr ""
#: ReactNativeClient/lib/models/Setting.js:230
msgid "Attachment download behaviour"
@@ -2827,8 +2823,9 @@ msgid "Web Clipper"
msgstr "Webクリッパー"
#: ReactNativeClient/lib/models/Setting.js:1259
#, fuzzy
msgid "Keyboard Shortcuts"
msgstr "キーボードショートカット"
msgstr "キーバインド"
#: ReactNativeClient/lib/models/Setting.js:1264
msgid ""
@@ -2983,8 +2980,6 @@ msgstr "いくつかの項目は同期されませんでした。詳細はクリ
#: ReactNativeClient/lib/components/screen-header.js:453
msgid "The sync target needs to be upgraded. Press this banner to proceed."
msgstr ""
"同期先をアップグレードする必要があります。アップグレードするにはバナーをク"
"リックしてください。"
#: ReactNativeClient/lib/components/side-menu-content.js:126
#, javascript-format
@@ -3029,8 +3024,8 @@ msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
"エラーです。URL、ユーザー名、パスワードなどを修正し、同期先にアクセスできるか"
"を確認してください。次が報告されたエラーです:"
"エラーです。URL、ユーザー名、パスワードなどを修正し、同期するターゲットにアク"
"セスできるかを確認してください。次が報告されたエラーです:"
#: ReactNativeClient/lib/components/shared/dropbox-login-shared.js:39
msgid "The application has been authorised!"
@@ -3107,7 +3102,7 @@ msgstr "更新"
#: ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js:42
msgid "Sync Target Upgrade"
msgstr "同期先のアップグレード"
msgstr ""
#: ReactNativeClient/lib/components/screens/NoteTagsDialog.js:163
msgid "New tags:"
@@ -3156,10 +3151,10 @@ msgid ""
"password as, for security purposes, this will be the *only* way to decrypt "
"the data! To enable encryption, please enter your password below."
msgstr ""
"暗号化を有効にするとは、*すべて*のノートや添付ファイルを再同期し、同期先に暗"
"号化した状態で送ることを意味します。パスワードはなくさないようにしてくださ"
"い。セキュリティ上、このパスワードがデータを復号する*唯一*の方法になるためで"
"す! 暗号化を有効にするには、下にパスワードを入力してください。"
"暗号化を有効にするとは、*すべて*のノートや添付ファイルを再同期し、同期ター"
"ゲットに暗号化した状態で送ることを意味します。パスワードはなくさないようにし"
"てください。セキュリティ上、このパスワードがデータを復号する*唯一*の方法にな"
"るためです! 暗号化を有効にするには、下にパスワードを入力してください。"
#: ReactNativeClient/lib/components/screens/encryption-config.js:177
msgid "Enable"
@@ -3551,35 +3546,32 @@ msgstr "ノートをどのノートブックにインポートするのか指定
#: ReactNativeClient/lib/services/KeymapService.js:124
#, javascript-format
msgid "Error loading the keymap from file: %s"
msgstr "キーマップ読み込みエラー(ファイル: %s)"
msgstr ""
#: ReactNativeClient/lib/services/KeymapService.js:141
#, javascript-format
msgid "Error saving the keymap to file: %s"
msgstr "キーマップ書き出しエラー(ファイル: %s)"
msgstr ""
#: ReactNativeClient/lib/services/KeymapService.js:204
#, javascript-format
msgid "Keymap item %s is missing the required \"command\" property."
msgstr ""
"キーマップアイテム %s は必須の \"command\" プロパティを持っていません。"
#: ReactNativeClient/lib/services/KeymapService.js:207
#, javascript-format
msgid "Keymap item %s is invalid because %s is not a valid command."
msgstr "キーマップアイテム %s は %s が有効なコマンドでないため無効です。"
msgstr ""
#: ReactNativeClient/lib/services/KeymapService.js:210
#, javascript-format
msgid "Keymap item %s is missing the required \"accelerator\" property."
msgstr ""
"キーマップアイテム %s は必須の \"accelerator\" プロパティを持っていません。"
#: ReactNativeClient/lib/services/KeymapService.js:217
#, javascript-format
msgid "Keymap item %s is invalid because %s is not a valid accelerator."
msgstr ""
"キーマップアイテム %s は %s が有効なショートカットキーでないため無効です。"
#: ReactNativeClient/lib/services/KeymapService.js:235
#, javascript-format
@@ -3587,13 +3579,11 @@ msgid ""
"Accelerator \"%s\" is used for \"%s\" and \"%s\" commands. This may lead to "
"unexpected behaviour."
msgstr ""
"ショートカットキー \"%s\" は \"%s\" コマンドと \"%s\" コマンドで使われていま"
"す。これにより予想外の動作が起こる可能性があります。"
#: ReactNativeClient/lib/services/KeymapService.js:260
#, javascript-format
msgid "Accelerator \"%s\" is not valid."
msgstr "ショートカットキー \"%s\" は無効です。"
msgstr ""
#: ReactNativeClient/lib/services/report.js:121
msgid "Items that cannot be synchronised"

File diff suppressed because it is too large Load Diff

View File

@@ -14,9 +14,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.4.1\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"X-Generator: Poedit 2.3.1\n"
#: CliClient/app/command-cp.js:13
msgid ""
@@ -321,7 +319,7 @@ msgstr ""
#: CliClient/app/command-sync.js:35
msgid "Upgrade the sync target to the latest version."
msgstr "Senkronizasyon hedefini en son sürüme yükseltin"
msgstr ""
#: CliClient/app/command-sync.js:81 CliClient/app/command-sync.js:95
#: ElectronClient/gui/OneDriveLoginScreen.min.js:40
@@ -815,8 +813,6 @@ msgstr "İptal et"
msgid ""
"The app is now going to close. Please relaunch it to complete the process."
msgstr ""
"Uygulama şimdi kapanacak. İşlemi tamamlamak için lütfen uygulamayı "
"kapandıktan sonar yeniden çalıştırın."
#: ElectronClient/plugins/GotoAnything.min.js:446
msgid ""
@@ -1177,13 +1173,13 @@ msgstr "Yeni %s oluşturuluyor..."
#: ElectronClient/gui/NoteEditor/NoteEditor.js:344
msgid "The following attachments are being watched for changes:"
msgstr "Şu ek dosyaları değişiklikler için izlenmekte:"
msgstr ""
#: ElectronClient/gui/NoteEditor/NoteEditor.js:347
msgid ""
"The attachments will no longer be watched when you switch to a different "
"note."
msgstr "Eğer başka bir not'a geçerseniz ek dosyalar artık izlenmeyecek."
msgstr ""
#: ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.js:25
msgid "Select all"
@@ -1294,7 +1290,7 @@ msgstr "Not özellikleri"
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:62
msgid "An unexpected error occured while importing the keymap!"
msgstr "Tuş dizimini içe aktarırken bir hata oluştu!"
msgstr ""
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:119
#: ElectronClient/gui/MainScreen/MainScreen.min.js:437
@@ -1309,11 +1305,12 @@ msgstr "İçe aktar"
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:125
msgid "Command"
msgstr "Komut"
msgstr ""
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:126
#, fuzzy
msgid "Keyboard Shortcut"
msgstr "Klavye Kısayolu"
msgstr "Klavye modu"
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:14
#: ElectronClient/app.js:690
@@ -1336,8 +1333,9 @@ msgid "Website and documentation"
msgstr "Web sitesi ve dökümanlar"
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:24
#, fuzzy
msgid "Hide Joplin"
msgstr "Joplin'i Gizle"
msgstr "Joplin hakkında"
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:26
#: ElectronClient/app.js:703
@@ -1345,8 +1343,9 @@ msgid "Close Window"
msgstr "Pencereyi Kapat"
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:28
#, fuzzy
msgid "Preferences"
msgstr "Tercihler"
msgstr "Tercihler..."
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:28
#: ElectronClient/gui/Root.min.js:92 ElectronClient/app.js:572
@@ -1355,15 +1354,13 @@ msgstr "Seçenekler"
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:48
msgid "Press the shortcut"
msgstr "Kısayolu girin"
msgstr ""
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:48
msgid ""
"Press the shortcut and then press ENTER. Or, press BACKSPACE to clear the "
"shortcut."
msgstr ""
"Kısayolu girin ve ardından ENTER tuşuna basın. Veya BACKSPACE tuşuna basarak "
"kısayolu temizleyin."
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:49
#: ElectronClient/gui/EncryptionConfigScreen.min.js:95
@@ -1377,14 +1374,11 @@ msgid ""
"may take a few minutes to complete and the app needs to be restarted. To "
"proceed please click on the link."
msgstr ""
"Senkronizasyon hedefi'nin Joplin senkronizasyona yeniden başlamadan once "
"güncellenmesi gerekir. Bu işlem notlarınızıın yoğunluğuna göre birkaç dakika "
"sürebilir, ve de bu işlem ardından uygulama yeniden başlatılacaktır. Bu "
"işlemi başlatmak için lütfen linke tıklayın."
#: ElectronClient/gui/MainScreen/MainScreen.min.js:306
#, fuzzy
msgid "Restart and upgrade"
msgstr "Yeniden başlat ve güncelle"
msgstr "Ana anahtarların güncellenmesi lazım"
#: ElectronClient/gui/MainScreen/MainScreen.min.js:313
msgid "Some items cannot be synchronised."
@@ -2144,8 +2138,9 @@ msgid "Templates"
msgstr "Şablonlar"
#: ElectronClient/app.js:668
#, fuzzy
msgid "Export all"
msgstr "Tümünü dışa aktar"
msgstr "Dışa aktar"
#: ElectronClient/app.js:683
#, javascript-format
@@ -2246,7 +2241,7 @@ msgstr "Bilinmeyen ID seviyesi: %s"
#: ReactNativeClient/lib/SyncTargetAmazonS3.js:28
msgid "AWS S3"
msgstr "AWS S3"
msgstr ""
#: ReactNativeClient/lib/SyncTargetDropbox.js:25
msgid "Dropbox"
@@ -2389,15 +2384,15 @@ msgstr "WebDAV şifresi"
#: ReactNativeClient/lib/models/Setting.js:195
msgid "AWS S3 bucket"
msgstr "AWS S3 deposu"
msgstr ""
#: ReactNativeClient/lib/models/Setting.js:206
msgid "AWS key"
msgstr "AWS anahtarı"
msgstr ""
#: ReactNativeClient/lib/models/Setting.js:216
msgid "AWS secret"
msgstr "AWS gizli anahtarı"
msgstr ""
#: ReactNativeClient/lib/models/Setting.js:230
msgid "Attachment download behaviour"
@@ -2855,8 +2850,9 @@ msgid "Web Clipper"
msgstr "Web Alıntılayıcısı"
#: ReactNativeClient/lib/models/Setting.js:1259
#, fuzzy
msgid "Keyboard Shortcuts"
msgstr "Klavye Kısayolları"
msgstr "Klavye modu"
#: ReactNativeClient/lib/models/Setting.js:1264
msgid ""
@@ -3012,8 +3008,6 @@ msgstr "Bazı öğeler senkronize edilemiyor. Detayları için tıklayın."
#: ReactNativeClient/lib/components/screen-header.js:453
msgid "The sync target needs to be upgraded. Press this banner to proceed."
msgstr ""
"Senkronizasyon hedefinin güncellenmesi gerekmekte. Bu banner'a tıklayarak "
"devam edebilirsiniz."
#: ReactNativeClient/lib/components/side-menu-content.js:126
#, javascript-format
@@ -3135,7 +3129,7 @@ msgstr "Yenile"
#: ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js:42
msgid "Sync Target Upgrade"
msgstr "Senkronizasyon Hedefi Güncellemesi"
msgstr ""
#: ReactNativeClient/lib/components/screens/NoteTagsDialog.js:163
msgid "New tags:"
@@ -3584,37 +3578,32 @@ msgstr "Lütfen notların alınacağı not defterini belirtin."
#: ReactNativeClient/lib/services/KeymapService.js:124
#, javascript-format
msgid "Error loading the keymap from file: %s"
msgstr "%s dosyasından tuş haritası yüklenemedi"
msgstr ""
#: ReactNativeClient/lib/services/KeymapService.js:141
#, javascript-format
msgid "Error saving the keymap to file: %s"
msgstr "%s dosyasına tuş haritası kaydedilemedi"
msgstr ""
#: ReactNativeClient/lib/services/KeymapService.js:204
#, javascript-format
msgid "Keymap item %s is missing the required \"command\" property."
msgstr ""
"%s tuş haritası, işlemler için gerekli olan \"command\" özelliğini "
"barındırmıyor."
#: ReactNativeClient/lib/services/KeymapService.js:207
#, javascript-format
msgid "Keymap item %s is invalid because %s is not a valid command."
msgstr "%s tuş haritası geçersizdir, çünkü %s geçerli bir komut değildir."
msgstr ""
#: ReactNativeClient/lib/services/KeymapService.js:210
#, javascript-format
msgid "Keymap item %s is missing the required \"accelerator\" property."
msgstr ""
"%s tuş haritası, işlemler için gerekli olan \"accelerator\" özelliğini "
"barındırmıyor."
#: ReactNativeClient/lib/services/KeymapService.js:217
#, javascript-format
msgid "Keymap item %s is invalid because %s is not a valid accelerator."
msgstr ""
"%s tuş haritası geçersizdir, çünkü %s geçerli bir accelerator değildir."
#: ReactNativeClient/lib/services/KeymapService.js:235
#, javascript-format
@@ -3622,13 +3611,11 @@ msgid ""
"Accelerator \"%s\" is used for \"%s\" and \"%s\" commands. This may lead to "
"unexpected behaviour."
msgstr ""
"Kısayol \"%s\", \"%s\" ve \"%s\" komutları için kullanılıyor. Bu beklenmeyen "
"sonuçlara sebep verebilir."
#: ReactNativeClient/lib/services/KeymapService.js:260
#, javascript-format
msgid "Accelerator \"%s\" is not valid."
msgstr "Kısayol \"%s\" geçersiz."
msgstr ""
#: ReactNativeClient/lib/services/report.js:121
msgid "Items that cannot be synchronised"
@@ -3962,7 +3949,7 @@ msgstr ""
#~ "Şu anda not defteriniz yok. (+) butonuna tıklayarak bir tane oluşturun."
#~ msgid "Welcome"
#~ msgstr "Hoş Geldiniz"
#~ msgstr "Hoşgeldiniz"
#~ msgid "Separate each tag by a comma."
#~ msgstr "Her etiketi virgülle ayırın."

View File

@@ -1,6 +1,6 @@
{
"name": "joplin",
"version": "1.2.2",
"version": "1.1.8",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -606,11 +606,6 @@
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
"dev": true
},
"builtin-modules": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz",
"integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw=="
},
"cache-base": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
@@ -4349,11 +4344,6 @@
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg=="
},
"nanoid": {
"version": "3.1.12",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz",
"integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A=="
},
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -5260,11 +5250,6 @@
}
}
},
"re-reselect": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/re-reselect/-/re-reselect-4.0.0.tgz",
"integrity": "sha512-wuygyq8TXUlSdVXv2kigXxQNOgdb9m7LbIjwfTNGSpaY1riLd5e+VeQjlQMyUtrk0oiyhi1AqIVynworl3qxHA=="
},
"read-chunk": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.1.0.tgz",
@@ -5625,11 +5610,6 @@
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"reselect": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz",
"integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA=="
},
"resolve": {
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
@@ -5900,11 +5880,6 @@
"is-fullwidth-code-point": "^2.0.0"
}
},
"slug": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/slug/-/slug-3.3.4.tgz",
"integrity": "sha512-VpHbtRCEWmgaZsrZcTsVl/Dhw98lcrOYDO17DNmJCNpppI6s3qJvnNu2Q3D4L84/2bi6vkW40mjNQI9oGQsflg=="
},
"snapdragon": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@@ -6767,6 +6742,11 @@
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
"integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc="
},
"unorm": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
"integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA=="
},
"unpack-string": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/unpack-string/-/unpack-string-0.0.2.tgz",
@@ -6869,6 +6849,14 @@
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
},
"uslug": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/uslug/-/uslug-1.0.4.tgz",
"integrity": "sha1-uaIvCRTgqGFAYz2swwLl9PpFBnc=",
"requires": {
"unorm": ">= 1.0.0"
}
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",

View File

@@ -28,7 +28,7 @@
],
"owner": "Laurent Cozic"
},
"version": "1.3.0",
"version": "1.1.8",
"bin": {
"joplin": "./main.js"
},
@@ -41,7 +41,6 @@
"aws-sdk": "^2.588.0",
"base-64": "^0.1.0",
"base64-stream": "^1.0.0",
"builtin-modules": "^3.1.0",
"clean-html": "^1.5.0",
"compare-version": "^0.1.2",
"diacritics": "^1.3.0",
@@ -84,7 +83,6 @@
"mime": "^2.0.3",
"moment": "^2.24.0",
"multiparty": "^4.2.1",
"nanoid": "^3.1.12",
"node-emoji": "^1.8.1",
"node-fetch": "^1.7.1",
"node-persist": "^2.1.0",
@@ -93,16 +91,13 @@
"promise": "^7.1.1",
"proper-lockfile": "^2.0.1",
"query-string": "4.3.4",
"re-reselect": "^4.0.0",
"read-chunk": "^2.1.0",
"redux": "^3.7.2",
"relative": "^3.0.2",
"request": "^2.88.0",
"reselect": "^4.0.0",
"sax": "^1.2.4",
"server-destroy": "^1.0.1",
"sharp": "^0.23.2",
"slug": "^3.3.4",
"sprintf-js": "^1.1.1",
"sqlite3": "^4.1.1",
"string-padding": "^1.0.2",
@@ -114,6 +109,7 @@
"terminal-kit": "^1.30.0",
"tkwidgets": "^0.5.26",
"url-parse": "^1.4.7",
"uslug": "^1.0.4",
"uuid": "^3.0.1",
"valid-url": "^1.0.9",
"word-wrap": "^1.2.3",

View File

@@ -1,7 +1,7 @@
require('app-module-path').addPath(__dirname);
const { asyncTest, setupDatabaseAndSynchronizer, switchClient } = require('test-utils.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
const { enexXmlToHtml } = require('lib/import-enex-html-gen.js');
process.on('unhandledRejection', (reason, p) => {

View File

@@ -9,7 +9,7 @@ const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const BaseModel = require('lib/BaseModel.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
const { enexXmlToMd } = require('lib/import-enex-md-gen.js');
process.on('unhandledRejection', (reason, p) => {

View File

@@ -9,7 +9,7 @@ const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const BaseModel = require('lib/BaseModel.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
const HtmlToHtml = require('lib/joplin-renderer/HtmlToHtml');
const { enexXmlToMd } = require('lib/import-enex-md-gen.js');

View File

@@ -9,7 +9,7 @@ const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const BaseModel = require('lib/BaseModel.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
const HtmlToMd = require('lib/HtmlToMd');
const { enexXmlToMd } = require('lib/import-enex-md-gen.js');

View File

@@ -9,7 +9,7 @@ const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const BaseModel = require('lib/BaseModel.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
const MdToHtml = require('lib/joplin-renderer/MdToHtml');
const { enexXmlToMd } = require('lib/import-enex-md-gen.js');
const { themeStyle } = require('lib/theme');

View File

@@ -1,4 +1,4 @@
const mdImporterService = require('lib/services/interop/InteropService_Importer_Md').default;
const mdImporterService = require('lib/services/InteropService_Importer_Md');
const Note = require('lib/models/Note.js');
const { setupDatabaseAndSynchronizer, switchClient } = require('test-utils.js');

View File

@@ -6,10 +6,10 @@ const { time } = require('lib/time-utils.js');
const { sortedIds, createNTestNotes, asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
const BaseModel = require('lib/BaseModel.js');
const ArrayUtils = require('lib/ArrayUtils.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);

View File

@@ -1,121 +0,0 @@
'use strict';
require('app-module-path').addPath(__dirname);
const { asyncTest,checkThrow } = require('test-utils.js');
const eventManager = require('lib/eventManager').default;
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
describe('eventManager', function() {
beforeEach(async (done) => {
eventManager.reset();
done();
});
afterEach(async (done) => {
eventManager.reset();
done();
});
it('should watch state props', asyncTest(async () => {
let localStateName = '';
let callCount = 0;
function nameWatch(event) {
callCount++;
localStateName = event.value;
}
const globalState = {
name: 'john',
};
eventManager.appStateOn('name', nameWatch);
eventManager.appStateEmit(globalState);
expect(localStateName).toBe('john');
globalState.name = 'paul';
eventManager.appStateEmit(globalState);
expect(localStateName).toBe('paul');
expect(callCount).toBe(2);
eventManager.appStateEmit(globalState);
expect(callCount).toBe(2);
}));
it('should unwatch state props', asyncTest(async () => {
let localStateName = '';
function nameWatch(event) {
localStateName = event.value;
}
const globalState = {
name: 'john',
};
eventManager.appStateOn('name', nameWatch);
eventManager.appStateOff('name', nameWatch);
eventManager.appStateEmit(globalState);
expect(localStateName).toBe('');
}));
it('should watch nested props', asyncTest(async () => {
let localStateName = '';
function nameWatch(event) {
localStateName = event.value;
}
const globalState = {
user: {
name: 'john',
},
};
eventManager.appStateOn('user.name', nameWatch);
eventManager.appStateEmit(globalState);
expect(localStateName).toBe('john');
globalState.user.name = 'paul';
eventManager.appStateEmit(globalState);
expect(localStateName).toBe('paul');
}));
it('should not be possible to modify state props', asyncTest(async () => {
let localUser = {};
function userWatch(event) {
// Normally, the user should not keep a reference to the whole object
// but make a copy. However, if they do keep a reference and try to
// modify it, it should throw an exception as that would be an attempt
// to directly modify the Redux state.
localUser = event.value;
}
const globalState = {
user: {
name: 'john',
},
};
eventManager.appStateOn('user', userWatch);
eventManager.appStateEmit(globalState);
expect(checkThrow(() => localUser.name = 'paul')).toBe(true);
}));
});

View File

@@ -1,7 +1,7 @@
require('app-module-path').addPath(__dirname);
const { asyncTest, id, ids, createNTestFolders, sortedIds, createNTestNotes, TestApp } = require('test-utils.js');
const BaseModel = require('lib/BaseModel.js');
const uuid = require('lib/uuid').default;
const { uuid } = require('lib/uuid.js');
const Note = require('lib/models/Note.js');
const Folder = require('lib/models/Folder.js');

View File

@@ -1,7 +1,7 @@
/* eslint-disable no-unused-vars */
require('app-module-path').addPath(__dirname);
const { setupDatabaseAndSynchronizer, switchClient, asyncTest, createNTestFolders, createNTestNotes, createNTestTags, TestApp } = require('test-utils.js');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Tag = require('lib/models/Tag.js');

View File

@@ -1,7 +1,7 @@
/* eslint-disable no-unused-vars */
require('app-module-path').addPath(__dirname);
const { setupDatabaseAndSynchronizer, switchClient, asyncTest, id, ids, sortedIds, at, createNTestFolders, createNTestNotes, createNTestTags, TestApp } = require('test-utils.js');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Tag = require('lib/models/Tag.js');

View File

@@ -1,7 +1,7 @@
/* eslint-disable no-unused-vars */
require('app-module-path').addPath(__dirname);
const { setupDatabaseAndSynchronizer, switchClient, asyncTest, createNTestFolders, createNTestNotes, createNTestTags, TestApp } = require('test-utils.js');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Tag = require('lib/models/Tag.js');

View File

@@ -2,12 +2,12 @@
require('app-module-path').addPath(__dirname);
const uuid = require('lib/uuid').default;
const { uuid } = require('lib/uuid.js');
const { time } = require('lib/time-utils.js');
const { asyncTest, sleep, fileApi, fileContentEqual, checkThrowAsync } = require('test-utils.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim.js');
const fs = require('fs-extra');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);

View File

@@ -9,7 +9,7 @@ const Note = require('lib/models/Note.js');
const BaseItem = require('lib/models/BaseItem.js');
const Resource = require('lib/models/Resource.js');
const BaseModel = require('lib/BaseModel.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);

View File

@@ -7,7 +7,7 @@ const { createNTestNotes, asyncTest, fileContentEqual, setupDatabase, setupDatab
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const BaseModel = require('lib/BaseModel.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);

View File

@@ -8,7 +8,7 @@ const SearchEngine = require('lib/services/searchengine/SearchEngine');
const ResourceService = require('lib/services/ResourceService');
const ItemChangeUtils = require('lib/services/ItemChangeUtils');
const Note = require('lib/models/Note');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting');
const ItemChange = require('lib/models/ItemChange');
process.on('unhandledRejection', (reason, p) => {

View File

@@ -6,10 +6,10 @@ const { time } = require('lib/time-utils.js');
const { sortedIds, createNTestNotes, asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
const BaseModel = require('lib/BaseModel.js');
const ArrayUtils = require('lib/ArrayUtils.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);

View File

@@ -6,10 +6,10 @@ const { time } = require('lib/time-utils.js');
const { sortedIds, createNTestNotes, asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
const BaseModel = require('lib/BaseModel.js');
const ArrayUtils = require('lib/ArrayUtils.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);

View File

@@ -8,7 +8,7 @@ const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Resource = require('lib/models/Resource.js');
const BaseModel = require('lib/BaseModel.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);

View File

@@ -10,7 +10,7 @@ const NoteTag = require('lib/models/NoteTag.js');
const Tag = require('lib/models/Tag.js');
const Revision = require('lib/models/Revision.js');
const BaseModel = require('lib/BaseModel.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);

View File

@@ -0,0 +1,37 @@
/* eslint-disable no-unused-vars */
require('app-module-path').addPath(__dirname);
const { time } = require('lib/time-utils.js');
const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const { shim } = require('lib/shim');
const Setting = require('lib/models/Setting.js');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
describe('models_Setting', function() {
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
done();
});
it('should return only sub-values', asyncTest(async () => {
const settings = {
'sync.5.path': 'http://example.com',
'sync.5.username': 'testing',
};
let output = Setting.subValues('sync.5', settings);
expect(output['path']).toBe('http://example.com');
expect(output['username']).toBe('testing');
output = Setting.subValues('sync.4', settings);
expect('path' in output).toBe(false);
expect('username' in output).toBe(false);
}));
});

View File

@@ -1,135 +0,0 @@
import Setting from 'lib/models/Setting';
require('app-module-path').addPath(__dirname);
const { asyncTest, setupDatabaseAndSynchronizer, switchClient, expectThrow, expectNotThrow } = require('test-utils.js');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
describe('models_Setting', function() {
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
done();
});
it('should return only sub-values', asyncTest(async () => {
const settings = {
'sync.5.path': 'http://example.com',
'sync.5.username': 'testing',
};
let output = Setting.subValues('sync.5', settings);
expect(output['path']).toBe('http://example.com');
expect(output['username']).toBe('testing');
output = Setting.subValues('sync.4', settings);
expect('path' in output).toBe(false);
expect('username' in output).toBe(false);
}));
it('should allow registering new settings dynamically', asyncTest(async () => {
await expectThrow(async () => Setting.setValue('myCustom', '123'));
await Setting.registerSetting('myCustom', {
public: true,
value: 'default',
type: Setting.TYPE_STRING,
});
await expectNotThrow(async () => Setting.setValue('myCustom', '123'));
expect(Setting.value('myCustom')).toBe('123');
}));
it('should not clear old custom settings', asyncTest(async () => {
// In general the following should work:
//
// - Plugin register a new setting
// - User set new value for setting
// - Settings are saved
// - => App restart
// - Plugin does not register setting again
// - Settings are loaded
// - Settings are saved
// - Plugin register setting again
// - Previous value set by user should still be there.
//
// In other words, once a custom setting has been set we don't clear it
// even if registration doesn't happen immediately. That allows for example
// to delay setting registration without a risk for the custom setting to be deleted.
await Setting.registerSetting('myCustom', {
public: true,
value: 'default',
type: Setting.TYPE_STRING,
});
Setting.setValue('myCustom', '123');
await Setting.saveAll();
await Setting.reset();
await Setting.load();
await Setting.registerSetting('myCustom', {
public: true,
value: 'default',
type: Setting.TYPE_STRING,
});
await Setting.saveAll();
expect(Setting.value('myCustom')).toBe('123');
}));
it('should return values with correct type for custom settings', asyncTest(async () => {
await Setting.registerSetting('myCustom', {
public: true,
value: 123,
type: Setting.TYPE_INT,
});
Setting.setValue('myCustom', 456);
await Setting.saveAll();
await Setting.reset();
await Setting.load();
await Setting.registerSetting('myCustom', {
public: true,
value: 123,
type: Setting.TYPE_INT,
});
expect(typeof Setting.value('myCustom')).toBe('number');
expect(Setting.value('myCustom')).toBe(456);
}));
it('should validate registered keys', asyncTest(async () => {
const md = {
public: true,
value: 'default',
type: Setting.TYPE_STRING,
};
await expectThrow(async () => await Setting.registerSetting('', md));
await expectThrow(async () => await Setting.registerSetting('no spaces', md));
await expectThrow(async () => await Setting.registerSetting('nospecialcharacters!!!', md));
await expectThrow(async () => await Setting.registerSetting('Robert\'); DROP TABLE Students;--', md));
await expectNotThrow(async () => await Setting.registerSetting('numbersareok123', md));
await expectNotThrow(async () => await Setting.registerSetting('so-ARE-dashes_123', md));
}));
it('should register new sections', asyncTest(async () => {
await Setting.registerSection('mySection', {
label: 'My section',
});
expect(Setting.sectionNameToLabel('mySection')).toBe('My section');
}));
});

View File

@@ -9,7 +9,7 @@ const Note = require('lib/models/Note.js');
const NoteTag = require('lib/models/NoteTag.js');
const Tag = require('lib/models/Tag.js');
const BaseModel = require('lib/BaseModel.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);

View File

@@ -5,8 +5,7 @@ const { setupDatabaseAndSynchronizer, switchClient, asyncTest, createNTestNotes,
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Tag = require('lib/models/Tag.js');
const reducer = require('lib/reducer').default;
const { defaultState, stateUtils, MAX_HISTORY } = require('lib/reducer');
const { reducer, defaultState, stateUtils, MAX_HISTORY } = require('lib/reducer.js');
function initTestState(folders, selectedFolderIndex, notes, selectedNoteIndexes, tags = null, selectedTagIndex = null) {
let state = defaultState;
@@ -88,7 +87,7 @@ function getIds(items, indexes = null) {
let insideBeforeEach = false;
describe('reducer', function() {
describe('Reducer', function() {
beforeEach(async (done) => {
insideBeforeEach = true;

View File

@@ -1,58 +0,0 @@
import sandboxProxy, { Target } from 'lib/services/plugins/sandboxProxy';
const { asyncTest, setupDatabaseAndSynchronizer, switchClient } = require('test-utils.js');
describe('services_plugins_sandboxProxy', function() {
beforeEach(async (done:Function) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
done();
});
it('should create a new sandbox proxy', asyncTest(async () => {
interface Result {
path: string,
args: any[],
}
const results:Result[] = [];
const target:Target = (path:string, args:any[]) => {
results.push({ path, args });
};
const proxy = sandboxProxy(target);
proxy.testing.bla.test('hello', '123');
proxy.testing.test2();
expect(results[0].path).toBe('testing.bla.test');
expect(results[0].args.join('_')).toBe('hello_123');
expect(results[1].path).toBe('testing.test2');
expect(results[1].args.join('_')).toBe('');
}));
it('should allow importing a namespace', asyncTest(async () => {
interface Result {
path: string,
args: any[],
}
const results:Result[] = [];
const target:Target = (path:string, args:any[]) => {
results.push({ path, args });
};
const proxy = sandboxProxy(target);
const ns = proxy.testing.blabla;
ns.test();
ns.test2();
expect(results[0].path).toBe('testing.blabla.test');
expect(results[1].path).toBe('testing.blabla.test2');
}));
});

View File

@@ -1,278 +0,0 @@
import MenuUtils from 'lib/services/commands/MenuUtils';
import ToolbarButtonUtils from 'lib/services/commands/ToolbarButtonUtils';
import CommandService, { CommandDeclaration, CommandRuntime } from 'lib/services/CommandService';
const { asyncTest, setupDatabaseAndSynchronizer, switchClient } = require('test-utils.js');
interface TestCommand {
declaration: CommandDeclaration,
runtime: CommandRuntime,
}
function newService():CommandService {
const service = new CommandService();
service.initialize({});
return service;
}
function createCommand(name:string, options:any):TestCommand {
const declaration:CommandDeclaration = {
name: name,
};
const runtime:CommandRuntime = {
execute: options.execute,
};
if (options.mapStateToProps) runtime.mapStateToProps = options.mapStateToProps;
if (options.isEnabled) runtime.isEnabled = options.isEnabled;
return { declaration, runtime };
}
function registerCommand(service:CommandService, cmd:TestCommand) {
service.registerDeclaration(cmd.declaration);
service.registerRuntime(cmd.declaration.name, cmd.runtime);
}
describe('services_CommandService', function() {
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
done();
});
it('should create toolbar button infos from commands', asyncTest(async () => {
const service = newService();
const toolbarButtonUtils = new ToolbarButtonUtils(service);
const executedCommands:string[] = [];
registerCommand(service, createCommand('test1', {
execute: () => {
executedCommands.push('test1');
},
}));
registerCommand(service, createCommand('test2', {
execute: () => {
executedCommands.push('test2');
},
}));
const toolbarInfos = toolbarButtonUtils.commandsToToolbarButtons({}, ['test1', 'test2']);
await toolbarInfos[0].onClick();
await toolbarInfos[1].onClick();
expect(executedCommands.join('_')).toBe('test1_test2');
expect(toolbarInfos[0].enabled).toBe(true);
expect(toolbarInfos[1].enabled).toBe(true);
}));
it('should enable and disable toolbar buttons depending on state', asyncTest(async () => {
const service = newService();
const toolbarButtonUtils = new ToolbarButtonUtils(service);
registerCommand(service, createCommand('test1', {
execute: () => {},
mapStateToProps: (state:any) => {
return {
selectedNoteId: state.selectedNoteId,
selectedFolderId: state.selectedFolderId,
};
},
isEnabled: (props:any) => {
return props.selectedNoteId === 'abc';
},
}));
registerCommand(service, createCommand('test2', {
execute: () => {},
mapStateToProps: (state:any) => {
return {
selectedNoteId: state.selectedNoteId,
selectedFolderId: state.selectedFolderId,
};
},
isEnabled: (props:any) => {
return props.selectedNoteId === '123';
},
}));
const toolbarInfos = toolbarButtonUtils.commandsToToolbarButtons({
selectedNoteId: '123',
selectedFolderId: 'aaa',
}, ['test1', 'test2']);
expect(toolbarInfos[0].enabled).toBe(false);
expect(toolbarInfos[1].enabled).toBe(true);
}));
it('should return the same toolbarButtons array if nothing has changed', asyncTest(async () => {
const service = newService();
const toolbarButtonUtils = new ToolbarButtonUtils(service);
registerCommand(service, createCommand('test1', {
execute: () => {},
mapStateToProps: (state:any) => {
return {
selectedNoteId: state.selectedNoteId,
};
},
isEnabled: (props:any) => {
return props.selectedNoteId === 'ok';
},
}));
registerCommand(service, createCommand('test2', {
execute: () => {},
mapStateToProps: (state:any) => {
return {
selectedFolderId: state.selectedFolderId,
};
},
isEnabled: (props:any) => {
return props.selectedFolderId === 'ok';
},
}));
const toolbarInfos1 = toolbarButtonUtils.commandsToToolbarButtons({
selectedNoteId: 'ok',
selectedFolderId: 'notok',
}, ['test1', 'test2']);
const toolbarInfos2 = toolbarButtonUtils.commandsToToolbarButtons({
selectedNoteId: 'ok',
selectedFolderId: 'notok',
}, ['test1', 'test2']);
expect(toolbarInfos1).toBe(toolbarInfos2);
expect(toolbarInfos1[0] === toolbarInfos2[0]).toBe(true);
expect(toolbarInfos1[1] === toolbarInfos2[1]).toBe(true);
const toolbarInfos3 = toolbarButtonUtils.commandsToToolbarButtons({
selectedNoteId: 'ok',
selectedFolderId: 'ok',
}, ['test1', 'test2']);
expect(toolbarInfos2 === toolbarInfos3).toBe(false);
expect(toolbarInfos2[0] === toolbarInfos3[0]).toBe(true);
expect(toolbarInfos2[1] === toolbarInfos3[1]).toBe(false);
{
expect(toolbarButtonUtils.commandsToToolbarButtons({
selectedNoteId: 'ok',
selectedFolderId: 'notok',
}, ['test1', '-', 'test2'])).toBe(toolbarButtonUtils.commandsToToolbarButtons({
selectedNoteId: 'ok',
selectedFolderId: 'notok',
}, ['test1', '-', 'test2']));
}
}));
it('should create menu items from commands', asyncTest(async () => {
const service = newService();
const utils = new MenuUtils(service);
registerCommand(service, createCommand('test1', {
execute: () => {},
}));
registerCommand(service, createCommand('test2', {
execute: () => {},
}));
const clickedCommands:string[] = [];
const onClick = (commandName:string) => {
clickedCommands.push(commandName);
};
const menuItems = utils.commandsToMenuItems(['test1', 'test2'], onClick);
menuItems.test1.click();
menuItems.test2.click();
expect(clickedCommands.join('_')).toBe('test1_test2');
// Also check that the same commands always return strictly the same menu
expect(utils.commandsToMenuItems(['test1', 'test2'], onClick)).toBe(utils.commandsToMenuItems(['test1', 'test2'], onClick));
}));
it('should give menu item props from state', asyncTest(async () => {
const service = newService();
const utils = new MenuUtils(service);
registerCommand(service, createCommand('test1', {
mapStateToProps: (state:any) => {
return {
isOk: state.test1 === 'ok',
};
},
execute: () => {},
}));
registerCommand(service, createCommand('test2', {
mapStateToProps: (state:any) => {
return {
isOk: state.test2 === 'ok',
};
},
execute: () => {},
}));
{
const menuItemProps = utils.commandsToMenuItemProps({
test1: 'ok',
test2: 'notok',
}, ['test1', 'test2']);
expect(menuItemProps.test1.isOk).toBe(true);
expect(menuItemProps.test2.isOk).toBe(false);
}
{
const menuItemProps = utils.commandsToMenuItemProps({
test1: 'ok',
test2: 'ok',
}, ['test1', 'test2']);
expect(menuItemProps.test1.isOk).toBe(true);
expect(menuItemProps.test2.isOk).toBe(true);
}
expect(utils.commandsToMenuItemProps({
test1: 'ok',
test2: 'ok',
}, ['test1', 'test2'])).toBe(utils.commandsToMenuItemProps({
test1: 'ok',
test2: 'ok',
}, ['test1', 'test2']));
}));
it('should create stateful menu items', asyncTest(async () => {
const service = newService();
const utils = new MenuUtils(service);
let propValue = null;
registerCommand(service, createCommand('test1', {
mapStateToProps: (state:any) => {
return {
isOk: state.test1 === 'ok',
};
},
execute: (props:any) => {
propValue = props.isOk;
},
}));
const menuItem = utils.commandToStatefulMenuItem('test1', { isOk: 'hello' });
menuItem.click();
expect(propValue).toBe('hello');
}));
});

View File

@@ -8,7 +8,7 @@ const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Tag = require('lib/models/Tag.js');
const { Database } = require('lib/database.js');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
const BaseItem = require('lib/models/BaseItem.js');
const BaseModel = require('lib/BaseModel.js');
const MasterKey = require('lib/models/MasterKey');
@@ -289,4 +289,35 @@ describe('services_EncryptionService', function() {
const plainText = await service.decryptString(cipherText);
expect(plainText).toBe('🐶🐶🐶'.substr(0,5));
}));
// it('should upgrade master key encryption mode', asyncTest(async () => {
// let masterKey = await service.generateMasterKey('123456', {
// encryptionMethod: EncryptionService.METHOD_SJCL_2,
// });
// masterKey = await MasterKey.save(masterKey);
// Setting.setObjectKey('encryption.passwordCache', masterKey.id, '123456');
// Setting.setValue('encryption.activeMasterKeyId', masterKey.id);
// await sleep(0.01);
// await service.loadMasterKeysFromSettings();
// masterKeyNew = await MasterKey.load(masterKey.id);
// // Check that the master key has been upgraded
// expect(masterKeyNew.created_time).toBe(masterKey.created_time);
// expect(masterKeyNew.updated_time === masterKey.updated_time).toBe(false);
// expect(masterKeyNew.content === masterKey.content).toBe(false);
// expect(masterKeyNew.encryption_method === masterKey.encryption_method).toBe(false);
// expect(masterKeyNew.checksum === masterKey.checksum).toBe(false);
// expect(masterKeyNew.encryption_method).toBe(service.defaultMasterKeyEncryptionMethod_);
// // Check that encryption still works
// const cipherText = await service.encryptString('some secret');
// const plainText = await service.decryptString(cipherText);
// expect(plainText).toBe('some secret');
// }));
});

View File

@@ -1,16 +1,19 @@
import InteropService from 'lib/services/interop/InteropService';
import { CustomExportContext, CustomImportContext, Module, ModuleType } from 'lib/services/interop/types';
import shim from 'lib/shim';
/* eslint-disable no-unused-vars */
require('app-module-path').addPath(__dirname);
const { asyncTest, fileContentEqual, setupDatabaseAndSynchronizer, switchClient, checkThrowAsync } = require('test-utils.js');
const { time } = require('lib/time-utils.js');
const { asyncTest, fileContentEqual, expectNotThrow, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const InteropService = require('lib/services/InteropService.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Tag = require('lib/models/Tag.js');
const NoteTag = require('lib/models/NoteTag.js');
const Resource = require('lib/models/Resource.js');
const fs = require('fs-extra');
const ArrayUtils = require('lib/ArrayUtils');
const ObjectUtils = require('lib/ObjectUtils');
const { shim } = require('lib/shim.js');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
@@ -20,7 +23,7 @@ function exportDir() {
return `${__dirname}/export`;
}
function fieldsEqual(model1:any, model2:any, fieldNames:string[]) {
function fieldsEqual(model1, model2, fieldNames) {
for (let i = 0; i < fieldNames.length; i++) {
const f = fieldNames[i];
expect(model1[f]).toBe(model2[f], `For key ${f}`);
@@ -40,7 +43,7 @@ describe('services_InteropService', function() {
});
it('should export and import folders', asyncTest(async () => {
const service = InteropService.instance();
const service = new InteropService();
let folder1 = await Folder.save({ title: 'folder1' });
folder1 = await Folder.load(folder1.id);
const filePath = `${exportDir()}/test.jex`;
@@ -75,7 +78,7 @@ describe('services_InteropService', function() {
}));
it('should import folders and de-duplicate titles when needed', asyncTest(async () => {
const service = InteropService.instance();
const service = new InteropService();
const folder1 = await Folder.save({ title: 'folder' });
const folder2 = await Folder.save({ title: 'folder' });
const filePath = `${exportDir()}/test.jex`;
@@ -87,15 +90,15 @@ describe('services_InteropService', function() {
await service.import({ path: filePath });
const allFolders = await Folder.all();
expect(allFolders.map((f:any) => f.title).sort().join(' - ')).toBe('folder - folder (1)');
expect(allFolders.map(f => f.title).sort().join(' - ')).toBe('folder - folder (1)');
}));
it('should import folders, and only de-duplicate titles when needed', asyncTest(async () => {
const service = InteropService.instance();
const service = new InteropService();
const folder1 = await Folder.save({ title: 'folder1' });
const folder2 = await Folder.save({ title: 'folder2' });
await Folder.save({ title: 'Sub', parent_id: folder1.id });
await Folder.save({ title: 'Sub', parent_id: folder2.id });
const sub1 = await Folder.save({ title: 'Sub', parent_id: folder1.id });
const sub2 = await Folder.save({ title: 'Sub', parent_id: folder2.id });
const filePath = `${exportDir()}/test.jex`;
await service.export({ path: filePath });
@@ -114,7 +117,7 @@ describe('services_InteropService', function() {
}));
it('should export and import folders and notes', asyncTest(async () => {
const service = InteropService.instance();
const service = new InteropService();
const folder1 = await Folder.save({ title: 'folder1' });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
note1 = await Note.load(note1.id);
@@ -153,7 +156,7 @@ describe('services_InteropService', function() {
}));
it('should export and import notes to specific folder', asyncTest(async () => {
const service = InteropService.instance();
const service = new InteropService();
const folder1 = await Folder.save({ title: 'folder1' });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
note1 = await Note.load(note1.id);
@@ -172,7 +175,7 @@ describe('services_InteropService', function() {
}));
it('should export and import tags', asyncTest(async () => {
const service = InteropService.instance();
const service = new InteropService();
const filePath = `${exportDir()}/test.jex`;
const folder1 = await Folder.save({ title: 'folder1' });
const note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
@@ -212,7 +215,7 @@ describe('services_InteropService', function() {
}));
it('should export and import resources', asyncTest(async () => {
const service = InteropService.instance();
const service = new InteropService();
const filePath = `${exportDir()}/test.jex`;
const folder1 = await Folder.save({ title: 'folder1' });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
@@ -248,7 +251,7 @@ describe('services_InteropService', function() {
}));
it('should export and import single notes', asyncTest(async () => {
const service = InteropService.instance();
const service = new InteropService();
const filePath = `${exportDir()}/test.jex`;
const folder1 = await Folder.save({ title: 'folder1' });
const note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
@@ -268,7 +271,7 @@ describe('services_InteropService', function() {
}));
it('should export and import single folders', asyncTest(async () => {
const service = InteropService.instance();
const service = new InteropService();
const filePath = `${exportDir()}/test.jex`;
const folder1 = await Folder.save({ title: 'folder1' });
const note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
@@ -289,7 +292,7 @@ describe('services_InteropService', function() {
it('should export and import folder and its sub-folders', asyncTest(async () => {
const service = InteropService.instance();
const service = new InteropService();
const filePath = `${exportDir()}/test.jex`;
const folder1 = await Folder.save({ title: 'folder1' });
const folder2 = await Folder.save({ title: 'folder2', parent_id: folder1.id });
@@ -323,7 +326,7 @@ describe('services_InteropService', function() {
}));
it('should export and import links to notes', asyncTest(async () => {
const service = InteropService.instance();
const service = new InteropService();
const filePath = `${exportDir()}/test.jex`;
const folder1 = await Folder.save({ title: 'folder1' });
const note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
@@ -346,21 +349,43 @@ describe('services_InteropService', function() {
expect(note2_2.body.indexOf(note1_2.id) >= 0).toBe(true);
}));
it('should export into json format', asyncTest(async () => {
const service = new InteropService();
const folder1 = await Folder.save({ title: 'folder1' });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
note1 = await Note.load(note1.id);
const filePath = exportDir();
await service.export({ path: filePath, format: 'json' });
// verify that the json files exist and can be parsed
const items = [folder1, note1];
for (let i = 0; i < items.length; i++) {
const jsonFile = `${filePath}/${items[i].id}.json`;
const json = await fs.readFile(jsonFile, 'utf-8');
const obj = JSON.parse(json);
expect(obj.id).toBe(items[i].id);
expect(obj.type_).toBe(items[i].type_);
expect(obj.title).toBe(items[i].title);
expect(obj.body).toBe(items[i].body);
}
}));
it('should export selected notes in md format', asyncTest(async () => {
const service = InteropService.instance();
const service = new InteropService();
const folder1 = await Folder.save({ title: 'folder1' });
let note11 = await Note.save({ title: 'title note11', parent_id: folder1.id });
note11 = await Note.load(note11.id);
const note12 = await Note.save({ title: 'title note12', parent_id: folder1.id });
await Note.load(note12.id);
let note12 = await Note.save({ title: 'title note12', parent_id: folder1.id });
note12 = await Note.load(note12.id);
let folder2 = await Folder.save({ title: 'folder2', parent_id: folder1.id });
folder2 = await Folder.load(folder2.id);
let note21 = await Note.save({ title: 'title note21', parent_id: folder2.id });
note21 = await Note.load(note21.id);
await Folder.save({ title: 'folder3', parent_id: folder1.id });
await Folder.load(folder2.id);
let folder3 = await Folder.save({ title: 'folder3', parent_id: folder1.id });
folder3 = await Folder.load(folder2.id);
const outDir = exportDir();
@@ -376,16 +401,16 @@ describe('services_InteropService', function() {
}));
it('should export MD with unicode filenames', asyncTest(async () => {
const service = InteropService.instance();
const service = new InteropService();
const folder1 = await Folder.save({ title: 'folder1' });
const folder2 = await Folder.save({ title: 'ジョプリン' });
await Note.save({ title: '生活', parent_id: folder1.id });
await Note.save({ title: '生活', parent_id: folder1.id });
await Note.save({ title: '生活', parent_id: folder1.id });
await Note.save({ title: '', parent_id: folder1.id });
await Note.save({ title: '', parent_id: folder1.id });
await Note.save({ title: 'salut, ça roule ?', parent_id: folder1.id });
await Note.save({ title: 'ジョプリン', parent_id: folder2.id });
const note1 = await Note.save({ title: '生活', parent_id: folder1.id });
const note2 = await Note.save({ title: '生活', parent_id: folder1.id });
const note2b = await Note.save({ title: '生活', parent_id: folder1.id });
const note3 = await Note.save({ title: '', parent_id: folder1.id });
const note4 = await Note.save({ title: '', parent_id: folder1.id });
const note5 = await Note.save({ title: 'salut, ça roule ?', parent_id: folder1.id });
const note6 = await Note.save({ title: 'ジョプリン', parent_id: folder2.id });
const outDir = exportDir();
@@ -405,7 +430,7 @@ describe('services_InteropService', function() {
await Note.save({ title: 'textexportnote1', parent_id: folder1.id });
await Note.save({ title: 'textexportnote2', parent_id: folder1.id });
const service = InteropService.instance();
const service = new InteropService();
await service.export({
path: exportDir(),
@@ -429,7 +454,7 @@ describe('services_InteropService', function() {
await Folder.save({ title: 'orphan', parent_id: '0c5bbd8a1b5a48189484a412a7e534cc' });
const service = InteropService.instance();
const service = new InteropService();
const result = await service.export({
path: exportDir(),
@@ -439,99 +464,4 @@ describe('services_InteropService', function() {
expect(result.warnings.length).toBe(0);
}));
it('should allow registering new import modules', asyncTest(async () => {
const testImportFilePath = `${exportDir()}/testImport${Math.random()}.test`;
await shim.fsDriver().writeFile(testImportFilePath, 'test', 'utf8');
const result = {
hasBeenExecuted: false,
sourcePath: '',
};
const module:Module = {
type: ModuleType.Importer,
description: 'Test Import Module',
format: 'testing',
fileExtensions: ['test'],
isCustom: true,
onExec: async (context:CustomImportContext) => {
result.hasBeenExecuted = true;
result.sourcePath = context.sourcePath;
},
};
const service = InteropService.instance();
service.registerModule(module);
await service.import({
format: 'testing',
path: testImportFilePath,
});
expect(result.hasBeenExecuted).toBe(true);
expect(result.sourcePath).toBe(testImportFilePath);
}));
it('should allow registering new export modules', asyncTest(async () => {
const folder1 = await Folder.save({ title: 'folder1' });
const note1 = await Note.save({ title: 'note1', parent_id: folder1.id });
await Note.save({ title: 'note2', parent_id: folder1.id });
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
const filePath = `${exportDir()}/example.test`;
const result:any = {
destPath: '',
itemTypes: [],
items: [],
resources: [],
filePaths: [],
closeCalled: false,
};
const module:Module = {
type: ModuleType.Exporter,
description: 'Test Export Module',
format: 'testing',
fileExtensions: ['test'],
isCustom: true,
onInit: async (context:CustomExportContext) => {
result.destPath = context.destPath;
},
onProcessItem: async (_context:CustomExportContext, itemType:number, item:any) => {
result.itemTypes.push(itemType);
result.items.push(item);
},
onProcessResource: async (_context:CustomExportContext, resource:any, filePath:string) => {
result.resources.push(resource);
result.filePaths.push(filePath);
},
onClose: async (_context:CustomExportContext) => {
result.closeCalled = true;
},
};
const service = InteropService.instance();
service.registerModule(module);
await service.export({
format: 'testing',
path: filePath,
});
expect(result.destPath).toBe(filePath);
expect(result.itemTypes.sort().join('_')).toBe('1_1_2_4');
expect(result.items.length).toBe(4);
expect(result.items.map((o:any) => o.title).sort().join('_')).toBe('folder1_note1_note2_photo.jpg');
expect(result.resources.length).toBe(1);
expect(result.resources[0].title).toBe('photo.jpg');
expect(result.filePaths.length).toBe(1);
expect(!!result.filePaths[0]).toBe(true);
expect(result.closeCalled).toBe(true);
}));
});

View File

@@ -4,12 +4,12 @@ require('app-module-path').addPath(__dirname);
const fs = require('fs-extra');
const { asyncTest, setupDatabaseAndSynchronizer, switchClient } = require('test-utils.js');
const InteropService_Exporter_Md = require('lib/services/interop/InteropService_Exporter_Md').default;
const InteropService_Exporter_Md = require('lib/services/InteropService_Exporter_Md.js');
const BaseModel = require('lib/BaseModel.js');
const Folder = require('lib/models/Folder.js');
const Resource = require('lib/models/Resource.js');
const Note = require('lib/models/Note.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim.js');
const exportDir = `${__dirname}/export`;
@@ -67,8 +67,8 @@ describe('services_InteropService_Exporter_Md', function() {
expect(!exporter.context() && !(exporter.context().notePaths || Object.keys(exporter.context().notePaths).length)).toBe(false, 'Context should be empty before processing.');
await exporter.processItem(Folder.modelType(), folder1);
await exporter.processItem(Folder.modelType(), folder2);
await exporter.processItem(Folder, folder1);
await exporter.processItem(Folder, folder2);
await exporter.prepareForProcessingItemType(BaseModel.TYPE_NOTE, itemsToExport);
expect(Object.keys(exporter.context().notePaths).length).toBe(3, 'There should be 3 note paths in the context.');
@@ -96,7 +96,7 @@ describe('services_InteropService_Exporter_Md', function() {
queueExportItem(BaseModel.TYPE_NOTE, note1);
queueExportItem(BaseModel.TYPE_NOTE, note1_2);
await exporter.processItem(Folder.modelType(), folder1);
await exporter.processItem(Folder, folder1);
await exporter.prepareForProcessingItemType(BaseModel.TYPE_NOTE, itemsToExport);
expect(Object.keys(exporter.context().notePaths).length).toBe(2, 'There should be 2 note paths in the context.');
@@ -121,7 +121,7 @@ describe('services_InteropService_Exporter_Md', function() {
queueExportItem(BaseModel.TYPE_FOLDER, folder1.id);
queueExportItem(BaseModel.TYPE_NOTE, note1);
await exporter.processItem(Folder.modelType(), folder1);
await exporter.processItem(Folder, folder1);
// Create a file with the path of note1 before processing note1
await shim.fsDriver().writeFile(`${exportDir}/folder1/note1.md`, 'Note content', 'utf-8');
@@ -189,10 +189,10 @@ describe('services_InteropService_Exporter_Md', function() {
const folder3 = await Folder.save({ title: 'folder3', parent_id: folder1.id });
queueExportItem(BaseModel.TYPE_FOLDER, folder3.id);
await exporter.processItem(Folder.modelType(), folder2);
await exporter.processItem(Folder.modelType(), folder3);
await exporter.processItem(Folder, folder2);
await exporter.processItem(Folder, folder3);
await exporter.prepareForProcessingItemType(BaseModel.TYPE_NOTE, itemsToExport);
await exporter.processItem(Note.modelType(), note2);
await exporter.processItem(Note, note2);
expect(await shim.fsDriver().exists(`${exportDir}/folder1`)).toBe(true, 'Folder should be created in filesystem.');
expect(await shim.fsDriver().exists(`${exportDir}/folder1/folder2`)).toBe(true, 'Folder should be created in filesystem.');
@@ -227,9 +227,9 @@ describe('services_InteropService_Exporter_Md', function() {
queueExportItem(BaseModel.TYPE_NOTE, note3);
await exporter.prepareForProcessingItemType(BaseModel.TYPE_NOTE, itemsToExport);
await exporter.processItem(Note.modelType(), note1);
await exporter.processItem(Note.modelType(), note2);
await exporter.processItem(Note.modelType(), note3);
await exporter.processItem(Note, note1);
await exporter.processItem(Note, note2);
await exporter.processItem(Note, note3);
expect(await shim.fsDriver().exists(`${exportDir}/${exporter.context().notePaths[note1.id]}`)).toBe(true, 'File should be saved in filesystem.');
expect(await shim.fsDriver().exists(`${exportDir}/${exporter.context().notePaths[note2.id]}`)).toBe(true, 'File should be saved in filesystem.');
@@ -262,8 +262,8 @@ describe('services_InteropService_Exporter_Md', function() {
queueExportItem(BaseModel.TYPE_NOTE, note2);
const resource2 = await Resource.load((await Note.linkedResourceIds(note2.body))[0]);
await exporter.processItem(Folder.modelType(), folder1);
await exporter.processItem(Folder.modelType(), folder2);
await exporter.processItem(Folder, folder1);
await exporter.processItem(Folder, folder2);
await exporter.prepareForProcessingItemType(BaseModel.TYPE_NOTE, itemsToExport);
const context = {
resourcePaths: {},
@@ -271,8 +271,8 @@ describe('services_InteropService_Exporter_Md', function() {
context.resourcePaths[resource1.id] = 'resource1.jpg';
context.resourcePaths[resource2.id] = 'resource2.jpg';
exporter.updateContext(context);
await exporter.processItem(Note.modelType(), note1);
await exporter.processItem(Note.modelType(), note2);
await exporter.processItem(Note, note1);
await exporter.processItem(Note, note2);
const note1_body = await shim.fsDriver().readFile(`${exportDir}/${exporter.context().notePaths[note1.id]}`);
const note2_body = await shim.fsDriver().readFile(`${exportDir}/${exporter.context().notePaths[note2.id]}`);
@@ -315,13 +315,13 @@ describe('services_InteropService_Exporter_Md', function() {
queueExportItem(BaseModel.TYPE_NOTE, note2);
queueExportItem(BaseModel.TYPE_NOTE, note3);
await exporter.processItem(Folder.modelType(), folder1);
await exporter.processItem(Folder.modelType(), folder2);
await exporter.processItem(Folder.modelType(), folder3);
await exporter.processItem(Folder, folder1);
await exporter.processItem(Folder, folder2);
await exporter.processItem(Folder, folder3);
await exporter.prepareForProcessingItemType(BaseModel.TYPE_NOTE, itemsToExport);
await exporter.processItem(Note.modelType(), note1);
await exporter.processItem(Note.modelType(), note2);
await exporter.processItem(Note.modelType(), note3);
await exporter.processItem(Note, note1);
await exporter.processItem(Note, note2);
await exporter.processItem(Note, note3);
const note1_body = await shim.fsDriver().readFile(`${exportDir}/${exporter.context().notePaths[note1.id]}`);
const note2_body = await shim.fsDriver().readFile(`${exportDir}/${exporter.context().notePaths[note2.id]}`);
@@ -351,10 +351,10 @@ describe('services_InteropService_Exporter_Md', function() {
queueExportItem(BaseModel.TYPE_NOTE, note1);
queueExportItem(BaseModel.TYPE_NOTE, note2);
await exporter.processItem(Folder.modelType(), folder1);
await exporter.processItem(Folder, folder1);
await exporter.prepareForProcessingItemType(BaseModel.TYPE_NOTE, itemsToExport);
await exporter.processItem(Note.modelType(), note1);
await exporter.processItem(Note.modelType(), note2);
await exporter.processItem(Note, note1);
await exporter.processItem(Note, note2);
const note2_body = await shim.fsDriver().readFile(`${exportDir}/${exporter.context().notePaths[note2.id]}`);
expect(note2_body).toContain('[link](../folder%20with%20space1/note1%20name%20with%20space.md)', 'Whitespace in URL should be encoded');

View File

@@ -1,6 +1,5 @@
require('app-module-path').addPath(__dirname);
const { tempFilePath } = require('test-utils.js');
const KeymapService = require('lib/services/KeymapService').default;
const keymapService = KeymapService.instance();
@@ -77,31 +76,6 @@ describe('services_KeymapService', () => {
});
});
describe('registerCommandAccelerator', () => {
beforeEach(() => keymapService.initialize());
it('should allow registering new commands', async () => {
keymapService.initialize('linux');
keymapService.registerCommandAccelerator('myCustomCommand', 'Ctrl+Shift+Alt+B');
expect(keymapService.getAccelerator('myCustomCommand')).toEqual('Ctrl+Shift+Alt+B');
// Check that macOS key conversion is working
keymapService.initialize('darwin');
keymapService.registerCommandAccelerator('myCustomCommand', 'CmdOrCtrl+Shift+Alt+B');
expect(keymapService.getAccelerator('myCustomCommand')).toEqual('Cmd+Shift+Option+B');
keymapService.setAccelerator('myCustomCommand', 'Cmd+Shift+Option+X');
// Check that the new custom shortcut is being saved and loaded
const keymapFilePath = tempFilePath('json');
await keymapService.saveCustomKeymap(keymapFilePath);
keymapService.initialize('darwin');
await keymapService.loadCustomKeymap(keymapFilePath);
expect(keymapService.getAccelerator('myCustomCommand')).toEqual('Cmd+Shift+Option+X');
});
});
describe('getAccelerator', () => {
beforeEach(() => keymapService.initialize());
@@ -280,15 +254,15 @@ describe('services_KeymapService', () => {
expect(() => keymapService.overrideKeymap(customKeymapItems)).toThrow();
});
// it('should throw when the provided commands are invalid', () => {
// const customKeymapItems = [
// { command: 'totallyInvalidCommand', accelerator: 'Ctrl+Shift+G' },
// { command: 'print', accelerator: 'Alt+P' },
// { command: 'focusElementNoteTitle', accelerator: 'Ctrl+Alt+Shift+J' },
// ];
it('should throw when the provided commands are invalid', () => {
const customKeymapItems = [
{ command: 'totallyInvalidCommand', accelerator: 'Ctrl+Shift+G' },
{ command: 'print', accelerator: 'Alt+P' },
{ command: 'focusElementNoteTitle', accelerator: 'Ctrl+Alt+Shift+J' },
];
// expect(() => keymapService.overrideKeymap(customKeymapItems)).toThrow();
// });
expect(() => keymapService.overrideKeymap(customKeymapItems)).toThrow();
});
it('should throw when duplicate accelerators are provided', () => {
const customKeymaps_Darwin = [

View File

@@ -1,93 +0,0 @@
import PluginRunner from '../app/services/plugins/PluginRunner';
import PluginService from 'lib/services/plugins/PluginService';
require('app-module-path').addPath(__dirname);
const { asyncTest, setupDatabaseAndSynchronizer, switchClient } = require('test-utils.js');
const Note = require('lib/models/Note');
const Folder = require('lib/models/Folder');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
const testPluginDir = `${__dirname}/../tests/support/plugins`;
function newPluginService() {
const runner = new PluginRunner();
const service = new PluginService();
service.initialize(
{
joplin: {
workspace: {},
},
},
runner,
{
dispatch: () => {},
getState: () => {},
}
);
return service;
}
describe('services_PluginService', function() {
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
done();
});
it('should load and run a simple plugin', asyncTest(async () => {
const service = newPluginService();
const plugin = await service.loadPlugin(`${testPluginDir}/simple`);
await service.runPlugin(plugin);
const allFolders = await Folder.all();
expect(allFolders.length).toBe(1);
expect(allFolders[0].title).toBe('my plugin folder');
const allNotes = await Note.all();
expect(allNotes.length).toBe(1);
expect(allNotes[0].title).toBe('testing plugin!');
expect(allNotes[0].parent_id).toBe(allFolders[0].id);
}));
it('should load and run a plugin that uses external packages', asyncTest(async () => {
const service = newPluginService();
const plugin = await service.loadPlugin(`${testPluginDir}/withExternalModules`);
expect(plugin.id).toBe('withexternalmodules');
await service.runPlugin(plugin);
const allFolders = await Folder.all();
expect(allFolders.length).toBe(1);
expect(allFolders[0].title).toBe(' foo');
}));
it('should load multiple plugins from a directory', asyncTest(async () => {
const service = newPluginService();
await service.loadAndRunPlugins(`${testPluginDir}/multi_plugins`);
const plugin1 = service.pluginById('simple1');
const plugin2 = service.pluginById('simple2');
expect(!!plugin1).toBe(true);
expect(!!plugin2).toBe(true);
const allFolders = await Folder.all();
expect(allFolders.length).toBe(2);
expect(allFolders.map((f:any) => f.title).sort().join(', ')).toBe('multi - simple1, multi - simple2');
}));
// it('should translate calls from plugin process to sandbox', asyncTest(async () => {
// const service = newPluginService();
// const plugin = await service.loadPlugin(`${testPluginDir}/simple`);
// await service.runPlugin(plugin);
// const folder = await Folder.save({ title: 'folder' });
// const folderFromApi = await service.executeSandboxCall(plugin.id, 'joplin.data.get', ['folders/' + folder.id]);
// expect(folder.id).toBe(folderFromApi.id);
// expect(folder.title).toBe(folderFromApi.title);
// }));
});

View File

@@ -4,7 +4,7 @@ require('app-module-path').addPath(__dirname);
const { time } = require('lib/time-utils.js');
const { asyncTest, resourceService, decryptionWorker, encryptionService, loadEncryptionMasterKey, allSyncTargetItemsEncrypted, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const InteropService = require('lib/services/interop/InteropService').default;
const InteropService = require('lib/services/InteropService.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Tag = require('lib/models/Tag.js');
@@ -16,7 +16,7 @@ const ResourceService = require('lib/services/ResourceService.js');
const fs = require('fs-extra');
const ArrayUtils = require('lib/ArrayUtils');
const ObjectUtils = require('lib/ObjectUtils');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim.js');
const SearchEngine = require('lib/services/searchengine/SearchEngine');
process.on('unhandledRejection', (reason, p) => {

View File

@@ -5,7 +5,7 @@ require('app-module-path').addPath(__dirname);
const { time } = require('lib/time-utils.js');
const { asyncTest, fileContentEqual, setupDatabase, revisionService, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const Folder = require('lib/models/Folder.js');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting.js');
const Note = require('lib/models/Note.js');
const NoteTag = require('lib/models/NoteTag.js');
const ItemChange = require('lib/models/ItemChange.js');
@@ -13,7 +13,7 @@ const Tag = require('lib/models/Tag.js');
const Revision = require('lib/models/Revision.js');
const BaseModel = require('lib/BaseModel.js');
const RevisionService = require('lib/services/RevisionService.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);

View File

@@ -8,7 +8,7 @@ const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, asyncTest
const SearchEngine = require('lib/services/searchengine/SearchEngine');
const Note = require('lib/models/Note');
const ItemChange = require('lib/models/ItemChange');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);

View File

@@ -10,9 +10,9 @@ const Note = require('lib/models/Note');
const Folder = require('lib/models/Folder');
const Tag = require('lib/models/Tag');
const ItemChange = require('lib/models/ItemChange');
const Setting = require('lib/models/Setting').default;
const Setting = require('lib/models/Setting');
const Resource = require('lib/models/Resource.js');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
const ResourceService = require('lib/services/ResourceService.js');

View File

@@ -1,162 +1,163 @@
/* eslint-disable no-unused-vars */
/* eslint prefer-const: 0*/
// require('app-module-path').addPath(__dirname);
require('app-module-path').addPath(__dirname);
// const { time } = require('lib/time-utils.js');
// const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, asyncTest, db, synchronizer, fileApi, sleep, createNTestNotes, switchClient, createNTestFolders } = require('test-utils.js');
// const SearchEngine = require('lib/services/searchengine/SearchEngine');
// const Note = require('lib/models/Note');
// const Folder = require('lib/models/Folder');
// const Tag = require('lib/models/Tag');
// const ItemChange = require('lib/models/ItemChange');
// const Setting = require('lib/models/Setting');
// const Resource = require('lib/models/Resource.js');
// const shim = require('lib/shim').default;
// const ResourceService = require('lib/services/ResourceService.js');
// process.on('unhandledRejection', (reason, p) => {
// console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
// });
// let engine = null;
// const ids = (array) => array.map(a => a.id);
// describe('services_SearchFuzzy', function() {
// beforeEach(async (done) => {
// await setupDatabaseAndSynchronizer(1);
// await switchClient(1);
// engine = new SearchEngine();
// engine.setDb(db());
// Setting.setValue('db.fuzzySearchEnabled', 1);
// done();
// });
const { time } = require('lib/time-utils.js');
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, asyncTest, db, synchronizer, fileApi, sleep, createNTestNotes, switchClient, createNTestFolders } = require('test-utils.js');
const SearchEngine = require('lib/services/searchengine/SearchEngine');
const Note = require('lib/models/Note');
const Folder = require('lib/models/Folder');
const Tag = require('lib/models/Tag');
const ItemChange = require('lib/models/ItemChange');
const Setting = require('lib/models/Setting');
const Resource = require('lib/models/Resource.js');
const { shim } = require('lib/shim');
const ResourceService = require('lib/services/ResourceService.js');
// it('should return note almost matching title', asyncTest(async () => {
// let rows;
// const n1 = await Note.save({ title: 'If It Ain\'t Baroque, Don\'t Fix It' });
// const n2 = await Note.save({ title: 'Important note' });
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
// await engine.syncTables();
// rows = await engine.search('Broke', { fuzzy: false });
// expect(rows.length).toBe(0);
let engine = null;
// rows = await engine.search('Broke', { fuzzy: true });
// expect(rows.length).toBe(1);
// expect(rows[0].id).toBe(n1.id);
const ids = (array) => array.map(a => a.id);
describe('services_SearchFuzzy', function() {
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
engine = new SearchEngine();
engine.setDb(db());
Setting.setValue('db.fuzzySearchEnabled', 1);
done();
});
// rows = await engine.search('title:Broke', { fuzzy: true });
// expect(rows.length).toBe(1);
// expect(rows[0].id).toBe(n1.id);
it('should return note almost matching title', asyncTest(async () => {
let rows;
const n1 = await Note.save({ title: 'If It Ain\'t Baroque, Don\'t Fix It' });
const n2 = await Note.save({ title: 'Important note' });
// rows = await engine.search('title:"Broke"', { fuzzy: true });
// expect(rows.length).toBe(1);
// expect(rows[0].id).toBe(n1.id);
await engine.syncTables();
rows = await engine.search('Broke', { fuzzy: false });
expect(rows.length).toBe(0);
// rows = await engine.search('Imprtant', { fuzzy: true });
// expect(rows.length).toBe(1);
// expect(rows[0].id).toBe(n2.id);
// }));
rows = await engine.search('Broke', { fuzzy: true });
expect(rows.length).toBe(1);
expect(rows[0].id).toBe(n1.id);
// it('should order results by min fuzziness', asyncTest(async () => {
// let rows;
// const n1 = await Note.save({ title: 'I demand you take me to him' });
// const n2 = await Note.save({ title: 'He demanded an answer' });
// const n3 = await Note.save({ title: 'Don\'t you make demands of me' });
// const n4 = await Note.save({ title: 'No drama for me' });
// const n5 = await Note.save({ title: 'Just minding my own business' });
rows = await engine.search('title:Broke', { fuzzy: true });
expect(rows.length).toBe(1);
expect(rows[0].id).toBe(n1.id);
// await engine.syncTables();
// rows = await engine.search('demand', { fuzzy: false });
// expect(rows.length).toBe(1);
// expect(rows[0].id).toBe(n1.id);
rows = await engine.search('title:"Broke"', { fuzzy: true });
expect(rows.length).toBe(1);
expect(rows[0].id).toBe(n1.id);
rows = await engine.search('Imprtant', { fuzzy: true });
expect(rows.length).toBe(1);
expect(rows[0].id).toBe(n2.id);
}));
// rows = await engine.search('demand', { fuzzy: true });
// expect(rows.length).toBe(3);
// expect(rows[0].id).toBe(n1.id);
// expect(rows[1].id).toBe(n3.id);
// expect(rows[2].id).toBe(n2.id);
// }));
it('should order results by min fuzziness', asyncTest(async () => {
let rows;
const n1 = await Note.save({ title: 'I demand you take me to him' });
const n2 = await Note.save({ title: 'He demanded an answer' });
const n3 = await Note.save({ title: 'Don\'t you make demands of me' });
const n4 = await Note.save({ title: 'No drama for me' });
const n5 = await Note.save({ title: 'Just minding my own business' });
// it('should consider any:1', asyncTest(async () => {
// let rows;
// const n1 = await Note.save({ title: 'cat' });
// const n2 = await Note.save({ title: 'cats' });
// const n3 = await Note.save({ title: 'cot' });
await engine.syncTables();
rows = await engine.search('demand', { fuzzy: false });
expect(rows.length).toBe(1);
expect(rows[0].id).toBe(n1.id);
// const n4 = await Note.save({ title: 'defenestrate' });
// const n5 = await Note.save({ title: 'defenstrate' });
// const n6 = await Note.save({ title: 'defenestrated' });
// const n7 = await Note.save({ title: 'he defenestrated the cat' });
rows = await engine.search('demand', { fuzzy: true });
expect(rows.length).toBe(3);
expect(rows[0].id).toBe(n1.id);
expect(rows[1].id).toBe(n3.id);
expect(rows[2].id).toBe(n2.id);
}));
// await engine.syncTables();
it('should consider any:1', asyncTest(async () => {
let rows;
const n1 = await Note.save({ title: 'cat' });
const n2 = await Note.save({ title: 'cats' });
const n3 = await Note.save({ title: 'cot' });
// rows = await engine.search('defenestrated cat', { fuzzy: true });
// expect(rows.length).toBe(1);
const n4 = await Note.save({ title: 'defenestrate' });
const n5 = await Note.save({ title: 'defenstrate' });
const n6 = await Note.save({ title: 'defenestrated' });
// rows = await engine.search('any:1 defenestrated cat', { fuzzy: true });
// expect(rows.length).toBe(7);
// }));
const n7 = await Note.save({ title: 'he defenestrated the cat' });
// it('should leave phrase searches alone', asyncTest(async () => {
// let rows;
// const n1 = await Note.save({ title: 'abc def' });
// const n2 = await Note.save({ title: 'def ghi' });
// const n3 = await Note.save({ title: 'ghi jkl' });
// const n4 = await Note.save({ title: 'def abc' });
// const n5 = await Note.save({ title: 'mno pqr ghi jkl' });
await engine.syncTables();
// await engine.syncTables();
rows = await engine.search('defenestrated cat', { fuzzy: true });
expect(rows.length).toBe(1);
// rows = await engine.search('abc def', { fuzzy: true });
// expect(rows.length).toBe(2);
// expect(rows.map(r=>r.id)).toContain(n1.id);
// expect(rows.map(r=>r.id)).toContain(n4.id);
rows = await engine.search('any:1 defenestrated cat', { fuzzy: true });
expect(rows.length).toBe(7);
}));
// rows = await engine.search('"abc def"', { fuzzy: true });
// expect(rows.length).toBe(1);
// expect(rows.map(r=>r.id)).toContain(n1.id);
it('should leave phrase searches alone', asyncTest(async () => {
let rows;
const n1 = await Note.save({ title: 'abc def' });
const n2 = await Note.save({ title: 'def ghi' });
const n3 = await Note.save({ title: 'ghi jkl' });
const n4 = await Note.save({ title: 'def abc' });
const n5 = await Note.save({ title: 'mno pqr ghi jkl' });
// rows = await engine.search('"ghi jkl"', { fuzzy: true });
// expect(rows.length).toBe(2);
// expect(rows.map(r=>r.id)).toContain(n3.id);
// expect(rows.map(r=>r.id)).toContain(n5.id);
await engine.syncTables();
// rows = await engine.search('"ghi jkl" mno', { fuzzy: true });
// expect(rows.length).toBe(1);
// expect(rows.map(r=>r.id)).toContain(n5.id);
rows = await engine.search('abc def', { fuzzy: true });
expect(rows.length).toBe(2);
expect(rows.map(r=>r.id)).toContain(n1.id);
expect(rows.map(r=>r.id)).toContain(n4.id);
// rows = await engine.search('any:1 "ghi jkl" mno', { fuzzy: true });
// expect(rows.length).toBe(2);
// expect(rows.map(r=>r.id)).toContain(n3.id);
// expect(rows.map(r=>r.id)).toContain(n5.id);
// }));
rows = await engine.search('"abc def"', { fuzzy: true });
expect(rows.length).toBe(1);
expect(rows.map(r=>r.id)).toContain(n1.id);
// it('should leave wild card searches alone', asyncTest(async () => {
// let rows;
// const n1 = await Note.save({ title: 'abc def' });
// const n2 = await Note.save({ title: 'abcc ghi' });
// const n3 = await Note.save({ title: 'abccc ghi' });
// const n4 = await Note.save({ title: 'abcccc ghi' });
// const n5 = await Note.save({ title: 'wxy zzz' });
rows = await engine.search('"ghi jkl"', { fuzzy: true });
expect(rows.length).toBe(2);
expect(rows.map(r=>r.id)).toContain(n3.id);
expect(rows.map(r=>r.id)).toContain(n5.id);
// await engine.syncTables();
rows = await engine.search('"ghi jkl" mno', { fuzzy: true });
expect(rows.length).toBe(1);
expect(rows.map(r=>r.id)).toContain(n5.id);
// rows = await engine.search('abc*', { fuzzy: true });
rows = await engine.search('any:1 "ghi jkl" mno', { fuzzy: true });
expect(rows.length).toBe(2);
expect(rows.map(r=>r.id)).toContain(n3.id);
expect(rows.map(r=>r.id)).toContain(n5.id);
}));
// expect(rows.length).toBe(4);
// expect(rows.map(r=>r.id)).toContain(n1.id);
// expect(rows.map(r=>r.id)).toContain(n2.id);
// expect(rows.map(r=>r.id)).toContain(n3.id);
// expect(rows.map(r=>r.id)).toContain(n4.id);
// }));
it('should leave wild card searches alone', asyncTest(async () => {
let rows;
const n1 = await Note.save({ title: 'abc def' });
const n2 = await Note.save({ title: 'abcc ghi' });
const n3 = await Note.save({ title: 'abccc ghi' });
const n4 = await Note.save({ title: 'abcccc ghi' });
const n5 = await Note.save({ title: 'wxy zzz' });
// });
await engine.syncTables();
rows = await engine.search('abc*', { fuzzy: true });
expect(rows.length).toBe(4);
expect(rows.map(r=>r.id)).toContain(n1.id);
expect(rows.map(r=>r.id)).toContain(n2.id);
expect(rows.map(r=>r.id)).toContain(n3.id);
expect(rows.map(r=>r.id)).toContain(n4.id);
}));
});

View File

@@ -0,0 +1,84 @@
// /* eslint-disable no-unused-vars */
// require('app-module-path').addPath(__dirname);
// const { asyncTest, fileContentEqual, setupDatabase, checkThrow, revisionService, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
// const KvStore = require('lib/services/KvStore.js');
// const UndoRedoService = require('lib/services/UndoRedoService.js').default;
// process.on('unhandledRejection', (reason, p) => {
// console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
// });
// describe('services_UndoRedoService', function() {
// beforeEach(async (done) => {
// await setupDatabaseAndSynchronizer(1);
// await switchClient(1);
// done();
// });
// it('should undo and redo', asyncTest(async () => {
// const service = new UndoRedoService();
// expect(service.canUndo).toBe(false);
// expect(service.canRedo).toBe(false);
// service.push('test');
// expect(service.canUndo).toBe(true);
// expect(service.canRedo).toBe(false);
// service.push('test 2');
// service.push('test 3');
// expect(service.undo()).toBe('test 3');
// expect(service.canRedo).toBe(true);
// expect(service.undo()).toBe('test 2');
// expect(service.undo()).toBe('test');
// expect(checkThrow(() => service.undo())).toBe(true);
// expect(service.canUndo).toBe(false);
// expect(service.canRedo).toBe(true);
// expect(service.redo()).toBe('test');
// expect(service.canUndo).toBe(true);
// expect(service.redo()).toBe('test 2');
// expect(service.redo()).toBe('test 3');
// expect(service.canRedo).toBe(false);
// expect(checkThrow(() => service.redo())).toBe(true);
// }));
// it('should clear the redo stack when undoing', asyncTest(async () => {
// const service = new UndoRedoService();
// service.push('test');
// service.push('test 2');
// service.push('test 3');
// service.undo();
// expect(service.canRedo).toBe(true);
// service.push('test 4');
// expect(service.canRedo).toBe(false);
// expect(service.undo()).toBe('test 4');
// expect(service.undo()).toBe('test 2');
// }));
// it('should limit the size of the undo stack', asyncTest(async () => {
// const service = new UndoRedoService();
// for (let i = 0; i < 30; i++) {
// service.push(`test${i}`);
// }
// for (let i = 0; i < 20; i++) {
// service.undo();
// }
// expect(service.canUndo).toBe(false);
// }));
// });

View File

@@ -3,8 +3,8 @@
require('app-module-path').addPath(__dirname);
const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const shim = require('lib/shim').default;
const Setting = require('lib/models/Setting').default;
const { shim } = require('lib/shim');
const Setting = require('lib/models/Setting');
const KeychainService = require('lib/services/keychain/KeychainService').default;
process.on('unhandledRejection', (reason, p) => {
@@ -50,7 +50,7 @@ describeIfCompatible('services_KeychainService', function() {
}));
it('should save and load secure settings', asyncTest(async () => {
Setting.setObjectValue('encryption.passwordCache', 'testing', '123456');
Setting.setObjectKey('encryption.passwordCache', 'testing', '123456');
await Setting.saveAll();
await Setting.load();
const passwords = Setting.value('encryption.passwordCache');

View File

@@ -9,7 +9,7 @@ const Resource = require('lib/models/Resource');
const Note = require('lib/models/Note');
const Tag = require('lib/models/Tag');
const NoteTag = require('lib/models/NoteTag');
const shim = require('lib/shim').default;
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);

View File

@@ -2,7 +2,6 @@
"spec_dir": "tests-build",
"spec_files": [
"*.js",
"services/plugins/*.js",
"!test-utils.js"
],
"stopSpecOnExpectationFailure": false,

View File

@@ -1 +0,0 @@
!function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e){var n=this&&this.__assign||function(){return(n=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var o in e=arguments[n])Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t}).apply(this,arguments)},r=this&&this.__awaiter||function(t,e,n,r){return new(n||(n=Promise))((function(o,i){function u(t){try{a(r.next(t))}catch(t){i(t)}}function l(t){try{a(r.throw(t))}catch(t){i(t)}}function a(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(u,l)}a((r=r.apply(t,e||[])).next())}))},o=this&&this.__generator||function(t,e){var n,r,o,i,u={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:l(0),throw:l(1),return:l(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function l(i){return function(l){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;u;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return u.label++,{value:i[1],done:!1};case 5:u.label++,r=i[1],i=[0];continue;case 7:i=u.ops.pop(),u.trys.pop();continue;default:if(!(o=u.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){u=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){u.label=i[1];break}if(6===i[0]&&u.label<o[1]){u.label=o[1],o=i;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(i);break}o[2]&&u.ops.pop(),u.trys.pop();continue}i=e.call(t,u)}catch(t){i=[6,t],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,l])}}};joplin.plugins.register({run:function(){return r(this,void 0,void 0,(function(){return o(this,(function(t){return joplin.filters.on("codeMirrorOptions",(function(t){return n(n({},t),{lineNumbers:!0})})),[2]}))}))}})}]);

View File

@@ -1,9 +0,0 @@
{
"manifest_version": 1,
"name": "To test setting preferences on CodeMirror editor",
"version": "1.0.0",
"homepage_url": "https://joplinapp.org",
"permissions": [
"model"
]
}

View File

@@ -1 +0,0 @@
declare var joplin:any;

Some files were not shown because too many files have changed in this diff Show More