You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2026-01-05 00:12:33 +02:00
Compare commits
297 Commits
v1.1.2
...
plugin_sys
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4693c924c3 | ||
|
|
833fb1264f | ||
|
|
6e7015e8f9 | ||
|
|
f007735936 | ||
|
|
1f1cd9f11b | ||
|
|
ac959b2882 | ||
|
|
4609634259 | ||
|
|
f06b64f3f9 | ||
|
|
80503ad0c1 | ||
|
|
05dfaf7347 | ||
|
|
59be83d958 | ||
|
|
e7676a148f | ||
|
|
73a39d36ea | ||
|
|
a43ab26a46 | ||
|
|
f5f117cb72 | ||
|
|
fc6da04081 | ||
|
|
12ff654986 | ||
|
|
e852ad846f | ||
|
|
cb28021a27 | ||
|
|
d8ab03f3bc | ||
|
|
48b6b83950 | ||
|
|
3e3bad0947 | ||
|
|
e527f590c5 | ||
|
|
88f968aac5 | ||
|
|
bbd01c3a38 | ||
|
|
e8d22a4177 | ||
|
|
6caec4df39 | ||
|
|
28e00fdf2e | ||
|
|
3bd0656eab | ||
|
|
e9af71dd76 | ||
|
|
73b33e8e32 | ||
|
|
eea56fcf94 | ||
|
|
a5a278eced | ||
|
|
a978ae4cfa | ||
|
|
c2c7efee91 | ||
|
|
c9c44d5643 | ||
|
|
0836fca822 | ||
|
|
566df5039c | ||
|
|
dd1c1dded4 | ||
|
|
5407481976 | ||
|
|
5a1f6b13cf | ||
|
|
a904431782 | ||
|
|
b23ec936fd | ||
|
|
73a4517902 | ||
|
|
a966b32583 | ||
|
|
91a3428124 | ||
|
|
93a5ba9490 | ||
|
|
e570f7a226 | ||
|
|
9b28a8995f | ||
|
|
197f509f5d | ||
|
|
559655bf33 | ||
|
|
0eab23fbcf | ||
|
|
f334f4f487 | ||
|
|
4c83d7aa75 | ||
|
|
17e053b358 | ||
|
|
a29c93634d | ||
|
|
a5f5bfcfec | ||
|
|
b509329383 | ||
|
|
91c7abed42 | ||
|
|
54fda6ac97 | ||
|
|
341eefebaf | ||
|
|
af714cbdac | ||
|
|
6a0bf15c28 | ||
|
|
5a2bdad348 | ||
|
|
fd08bfdd86 | ||
|
|
1a5cead659 | ||
|
|
85df133386 | ||
|
|
869d11e113 | ||
|
|
d7a01d3965 | ||
|
|
989036241d | ||
|
|
433cef1827 | ||
|
|
433d34f62b | ||
|
|
e7ec33bbf9 | ||
|
|
a29f42d78d | ||
|
|
74ed234ab9 | ||
|
|
49bfa49489 | ||
|
|
5f81944a3e | ||
|
|
86b76ccb77 | ||
|
|
29aedf8480 | ||
|
|
9486f5e0d2 | ||
|
|
9a458431b8 | ||
|
|
2c9db9d18c | ||
|
|
ae9c535842 | ||
|
|
a518da587e | ||
|
|
92e6e00d9e | ||
|
|
b64c9cf18a | ||
|
|
275d6e230d | ||
|
|
ab8ce15c33 | ||
|
|
3fb6179587 | ||
|
|
28cc38064c | ||
|
|
1fa5ab2b96 | ||
|
|
15f4e635d9 | ||
|
|
7a79d7ef7e | ||
|
|
776e7dfe3f | ||
|
|
790b622cbc | ||
|
|
89117b4ee9 | ||
|
|
c245517e0f | ||
|
|
31db95d0c4 | ||
|
|
2cd50de065 | ||
|
|
6dcb7e2605 | ||
|
|
9c9bd4ba51 | ||
|
|
71e6964945 | ||
|
|
00057da17d | ||
|
|
0a05464013 | ||
|
|
97dc2fa6bd | ||
|
|
161e112e7b | ||
|
|
c93a6f86cd | ||
|
|
9bb178b9d9 | ||
|
|
8087bc5280 | ||
|
|
26f5a606e0 | ||
|
|
9ebb574059 | ||
|
|
d29c3c2466 | ||
|
|
a71f1c19ec | ||
|
|
485921d879 | ||
|
|
15de7572c0 | ||
|
|
09f41dd50e | ||
|
|
7b8ee467a0 | ||
|
|
99a496d684 | ||
|
|
100aaab58d | ||
|
|
126c7b5a75 | ||
|
|
d448ea3a02 | ||
|
|
9d6975a9e2 | ||
|
|
555727e5fe | ||
|
|
f43ee123d8 | ||
|
|
f42fb1b871 | ||
|
|
cf2442c5b2 | ||
|
|
e0e4735b03 | ||
|
|
138faa2aae | ||
|
|
8bd58c9608 | ||
|
|
215a725ded | ||
|
|
12c0a05af0 | ||
|
|
a7fa119041 | ||
|
|
7fb52b8b0e | ||
|
|
3e86ae4a82 | ||
|
|
77eceea426 | ||
|
|
a09c6f152c | ||
|
|
3830195752 | ||
|
|
c9594065c3 | ||
|
|
360d3bbff9 | ||
|
|
6fde8dfe52 | ||
|
|
de2ccfbfe0 | ||
|
|
31f53b12fd | ||
|
|
d45b280ada | ||
|
|
ca46590ff3 | ||
|
|
b5a137545e | ||
|
|
4e80dbb7a7 | ||
|
|
90b0c99806 | ||
|
|
947d81d96d | ||
|
|
6ca640d2ed | ||
|
|
c8c0c3af46 | ||
|
|
110de50bf9 | ||
|
|
b7e110d888 | ||
|
|
f1c557cb43 | ||
|
|
43e9fc92c9 | ||
|
|
10fa331731 | ||
|
|
cc8e122de3 | ||
|
|
bca5fd8db9 | ||
|
|
13101f7d9b | ||
|
|
6aca233b21 | ||
|
|
2200be697e | ||
|
|
25ab3c323b | ||
|
|
5bf30a9586 | ||
|
|
b6779a8074 | ||
|
|
59599d318c | ||
|
|
538600fd6c | ||
|
|
63264ba471 | ||
|
|
95e7f3df7d | ||
|
|
366fd2a333 | ||
|
|
5be99a4a16 | ||
|
|
d86f6a1fbd | ||
|
|
7d68208cb4 | ||
|
|
e9de9d9128 | ||
|
|
1af16d9f0b | ||
|
|
8e11eababa | ||
|
|
4ec9faadd5 | ||
|
|
5cf462c885 | ||
|
|
f7ef0a2b1e | ||
|
|
870f55a6c5 | ||
|
|
7f7e38b434 | ||
|
|
460a07b1a3 | ||
|
|
48c9b86d2b | ||
|
|
7202066c1f | ||
|
|
5226f0019b | ||
|
|
26ac745419 | ||
|
|
b3f2bbee5b | ||
|
|
56c6cfc785 | ||
|
|
1db4932573 | ||
|
|
a2873ebbc5 | ||
|
|
f652011d59 | ||
|
|
27c572b2f5 | ||
|
|
7a4c97618d | ||
|
|
3ac4fbeee5 | ||
|
|
9e05fa553c | ||
|
|
d4f0d2423d | ||
|
|
abdd7e3256 | ||
|
|
f3ea476f27 | ||
|
|
aa22af443c | ||
|
|
ce3bd2a47d | ||
|
|
a9b26246e6 | ||
|
|
cc1e941dd9 | ||
|
|
9610b7e6bd | ||
|
|
4f2884a0f7 | ||
|
|
4872f1419c | ||
|
|
fdcaab3caf | ||
|
|
9f2c4b938f | ||
|
|
8be65acf7d | ||
|
|
ad85a12535 | ||
|
|
b825346829 | ||
|
|
bd4cbaf93d | ||
|
|
e05aa433e4 | ||
|
|
ccfb0b43d6 | ||
|
|
4211e962c6 | ||
|
|
9af2a19bdf | ||
|
|
d3fa906a9a | ||
|
|
6b54c4244b | ||
|
|
1d5a4bd381 | ||
|
|
86a1103a64 | ||
|
|
45edaaa96f | ||
|
|
b7b158aa94 | ||
|
|
e6bc55b6f8 | ||
|
|
111092791c | ||
|
|
4e91e01ddc | ||
|
|
44dce6c6c3 | ||
|
|
b25ad50a1b | ||
|
|
22679641ee | ||
|
|
e2e3be66ee | ||
|
|
4b3119ebba | ||
|
|
1712a67e2e | ||
|
|
cd563b050c | ||
|
|
4426f2dbec | ||
|
|
0fbbf2eee0 | ||
|
|
0ca7457000 | ||
|
|
c84e49c71c | ||
|
|
07ab0e986d | ||
|
|
17957f5da4 | ||
|
|
a7b5d43e69 | ||
|
|
38eda3f151 | ||
|
|
2fdad2fe80 | ||
|
|
0249ff48ca | ||
|
|
142fc02f9c | ||
|
|
842b123285 | ||
|
|
a4aca68b85 | ||
|
|
1397af0692 | ||
|
|
5da760dd0c | ||
|
|
511d58d3af | ||
|
|
a1c9e675ad | ||
|
|
0349ad0b80 | ||
|
|
056285deda | ||
|
|
9d8411a25e | ||
|
|
754ba2267a | ||
|
|
bdedf69439 | ||
|
|
4cdac308d1 | ||
|
|
c0d5c7c282 | ||
|
|
f9296992bf | ||
|
|
5b06ebde1e | ||
|
|
d309c75974 | ||
|
|
807c89a42f | ||
|
|
0b8350e9ea | ||
|
|
49e7be8924 | ||
|
|
810c63e3b2 | ||
|
|
d917ca5551 | ||
|
|
ec642300ab | ||
|
|
9034d646bf | ||
|
|
96f6bbb035 | ||
|
|
e14ed655d2 | ||
|
|
54e5323f54 | ||
|
|
ef58affed1 | ||
|
|
76fa87d878 | ||
|
|
2db2225788 | ||
|
|
425c1763f4 | ||
|
|
044f2eac6a | ||
|
|
281f135125 | ||
|
|
6c88f8b8ae | ||
|
|
832abcddf0 | ||
|
|
e6c481f45c | ||
|
|
11fecfb83a | ||
|
|
2facc9868e | ||
|
|
7b9ad9d1c3 | ||
|
|
3b96a99f3e | ||
|
|
575ce5128b | ||
|
|
dece28da35 | ||
|
|
2ffc429971 | ||
|
|
8baa125842 | ||
|
|
6b6092ffc7 | ||
|
|
714c912aff | ||
|
|
ebf8b744e1 | ||
|
|
1039e98396 | ||
|
|
8f00538cb1 | ||
|
|
2b530a3ff9 | ||
|
|
d089511aa6 | ||
|
|
450c8dbf22 | ||
|
|
94d87285dc | ||
|
|
ffeb7d0ecd | ||
|
|
aba92857cb | ||
|
|
5918c81dbb | ||
|
|
819d9fd977 | ||
|
|
ad80e074de |
138
.eslintignore
138
.eslintignore
@@ -59,18 +59,32 @@ 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/build/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/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
|
||||
@@ -81,8 +95,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
|
||||
@@ -94,9 +108,12 @@ 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
|
||||
@@ -113,9 +130,11 @@ 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
|
||||
@@ -125,44 +144,144 @@ 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/errorUtils.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/markdownUtils.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/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/api/types.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
|
||||
ReactNativeClient/lib/services/rest/Api.js
|
||||
ReactNativeClient/lib/services/rest/errors.js
|
||||
ReactNativeClient/lib/services/searchengine/filterParser.js
|
||||
ReactNativeClient/lib/services/searchengine/queryBuilder.js
|
||||
@@ -176,6 +295,19 @@ 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
|
||||
|
||||
16
.eslintrc.js
16
.eslintrc.js
@@ -48,8 +48,9 @@ module.exports = {
|
||||
// -------------------------------
|
||||
'react/jsx-uses-react': 'error',
|
||||
'react/jsx-uses-vars': 'error',
|
||||
'no-unused-vars': 'error',
|
||||
'@typescript-eslint/no-unused-vars': 'error',
|
||||
'no-unused-vars': ['error', { 'argsIgnorePattern': '^_' }],
|
||||
'@typescript-eslint/no-unused-vars': ['error', { 'argsIgnorePattern': '^_' }],
|
||||
'@typescript-eslint/explicit-member-accessibility': 'off',
|
||||
'no-constant-condition': 0,
|
||||
'no-prototype-builtins': 0,
|
||||
// This error is always a false positive so far since it detects
|
||||
@@ -121,4 +122,15 @@ 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'],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
143
.gitignore
vendored
143
.gitignore
vendored
@@ -50,20 +50,35 @@ joplin-webclipper-source.zip
|
||||
Tools/commit_hook.txt
|
||||
.vscode/*
|
||||
*.map
|
||||
ReactNativeClient/lib/sql-extensions/
|
||||
!ReactNativeClient/lib/sql-extensions/spellfix.dll
|
||||
ReactNativeClient/lib/sql-extensions/spellfix.so
|
||||
ReactNativeClient/lib/sql-extensions/spellfix.dylib
|
||||
CliClient/build/
|
||||
plugin_types/
|
||||
|
||||
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
|
||||
CliClient/app/LinkSelector.js
|
||||
CliClient/build/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/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
|
||||
@@ -74,8 +89,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
|
||||
@@ -87,9 +102,12 @@ 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
|
||||
@@ -106,9 +124,11 @@ 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
|
||||
@@ -118,44 +138,144 @@ 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/errorUtils.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/markdownUtils.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/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/api/types.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
|
||||
ReactNativeClient/lib/services/rest/Api.js
|
||||
ReactNativeClient/lib/services/rest/errors.js
|
||||
ReactNativeClient/lib/services/searchengine/filterParser.js
|
||||
ReactNativeClient/lib/services/searchengine/queryBuilder.js
|
||||
@@ -169,6 +289,19 @@ 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
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
5
BUILD.md
5
BUILD.md
@@ -11,6 +11,7 @@ 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
|
||||
|
||||
@@ -25,6 +26,8 @@ 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
|
||||
@@ -93,4 +96,4 @@ The Markdown renderer is located under ReactNativeClient/lib/joplin-renderer. Wh
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
Please read for the [Build Troubleshooting Document](https://github.com/laurent22/joplin/blob/master/readme/build_troubleshooting.md) for various tips on how to get the build working.
|
||||
Please read for the [Build Troubleshooting Document](https://github.com/laurent22/joplin/blob/dev/readme/build_troubleshooting.md) for various tips on how to get the build working.
|
||||
@@ -1,4 +1,4 @@
|
||||
const { Logger } = require('lib/logger.js');
|
||||
const Logger = require('lib/Logger').default;
|
||||
const { netUtils } = require('lib/net-utils.js');
|
||||
|
||||
const http = require('http');
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
const { Logger } = require('lib/logger.js');
|
||||
const Logger = require('lib/Logger').default;
|
||||
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.js');
|
||||
const { reducer, defaultState } = require('lib/reducer.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const reducer = require('lib/reducer').default;
|
||||
const { defaultState } = require('lib/reducer');
|
||||
const { splitCommandString } = require('lib/string-utils.js');
|
||||
const { reg } = require('lib/registry.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const shim = require('lib/shim').default;
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlentities = new Entities().encode;
|
||||
|
||||
@@ -477,7 +479,7 @@ class AppGui {
|
||||
this.linkSelector_.noteX + cursorOffsetX,
|
||||
this.linkSelector_.noteY + cursorOffsetY
|
||||
);
|
||||
setTimeout(() => this.term_.term().inverse(this.linkSelector_.link), 50);
|
||||
shim.setTimeout(() => this.term_.term().inverse(this.linkSelector_.link), 50);
|
||||
}
|
||||
} else if (cmd === 'open_link') {
|
||||
if (this.widget('noteText').hasFocus) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { BaseApplication } = require('lib/BaseApplication');
|
||||
const BaseApplication = require('lib/BaseApplication').default;
|
||||
const { FoldersScreenUtils } = require('lib/folders-screen-utils.js');
|
||||
const ResourceService = require('lib/services/ResourceService');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
@@ -6,14 +6,15 @@ 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.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const { reg } = require('lib/registry.js');
|
||||
const { fileExtension } = require('lib/path-utils.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
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() {
|
||||
@@ -161,7 +162,7 @@ class Application extends BaseApplication {
|
||||
};
|
||||
|
||||
// Give it a few seconds to cancel otherwise exit anyway
|
||||
setTimeout(async () => {
|
||||
shim.setTimeout(async () => {
|
||||
await doExit();
|
||||
}, 5000);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const { reg } = require('lib/registry.js');
|
||||
|
||||
class BaseCommand {
|
||||
|
||||
@@ -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.js');
|
||||
const { languageCode } = require('lib/locale');
|
||||
|
||||
const rootDir = dirname(dirname(__dirname));
|
||||
const MAX_WIDTH = 78;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs-extra');
|
||||
const { Logger } = require('lib/logger.js');
|
||||
const Logger = require('lib/Logger').default;
|
||||
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.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const { sprintf } = require('sprintf-js');
|
||||
const exec = require('child_process').exec;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const yargParser = require('yargs-parser');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
const stringPadding = require('string-padding');
|
||||
const { Logger } = require('lib/logger.js');
|
||||
const Logger = require('lib/Logger').default;
|
||||
|
||||
const cliUtils = {};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ const BaseItem = require('lib/models/BaseItem');
|
||||
const BaseModel = require('lib/BaseModel');
|
||||
const { toTitleCase } = require('lib/string-utils.js');
|
||||
const { reg } = require('lib/registry.js');
|
||||
const markdownUtils = require('lib/markdownUtils');
|
||||
const markdownUtils = require('lib/markdownUtils').default;
|
||||
const { Database } = require('lib/database.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
@@ -53,9 +53,9 @@ class Command extends BaseCommand {
|
||||
|
||||
const lines = [];
|
||||
|
||||
lines.push('# Joplin API');
|
||||
lines.push('# Joplin Data API');
|
||||
lines.push('');
|
||||
|
||||
lines.push('This API is available when the clipper server is running. It provides access to the notes, notebooks, tags and other Joplin object via a REST API. Plugins can also access this API even when the clipper server is not running.');
|
||||
lines.push('');
|
||||
lines.push('In order to use it, you\'ll first need to find on which port the service is running. To do so, open the Web Clipper Options in Joplin and if the service is running it should tell you on which port. Normally it runs on port **41184**. If you want to find it programmatically, you may follow this kind of algorithm:');
|
||||
lines.push('');
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const { shim } = require('lib/shim.js');
|
||||
const shim = require('lib/shim').default;
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const BaseItem = require('lib/models/BaseItem.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { _, setLocale } = require('lib/locale.js');
|
||||
const { _, setLocale } = require('lib/locale');
|
||||
const { app } = require('./app.js');
|
||||
const fs = require('fs-extra');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const EncryptionService = require('lib/services/EncryptionService');
|
||||
const DecryptionWorker = require('lib/services/DecryptionWorker');
|
||||
const BaseItem = require('lib/models/BaseItem');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const { shim } = require('lib/shim');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const shim = require('lib/shim').default;
|
||||
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.setObjectKey('encryption.passwordCache', masterKeyId, password);
|
||||
Setting.setObjectValue('encryption.passwordCache', masterKeyId, password);
|
||||
await EncryptionService.instance().loadMasterKeysFromSettings();
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -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.js');
|
||||
const uuid = require('lib/uuid').default;
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const { ReportService } = require('lib/services/report.js');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const InteropService = require('lib/services/InteropService.js');
|
||||
const InteropService = require('lib/services/interop/InteropService').default;
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
||||
@@ -14,7 +14,7 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
options() {
|
||||
const service = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
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 = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
const result = await service.export(exportOptions);
|
||||
|
||||
result.warnings.map(w => this.stdout(w));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
|
||||
|
||||
@@ -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.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const { cliUtils } = require('./cli-utils.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const InteropService = require('lib/services/InteropService.js');
|
||||
const InteropService = require('lib/services/interop/InteropService').default;
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const { cliUtils } = require('./cli-utils.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
||||
@@ -15,7 +15,7 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
options() {
|
||||
const service = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
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 = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
const result = await service.import(importOptions);
|
||||
result.warnings.map(w => this.stdout(w));
|
||||
cliUtils.redrawDone();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const Note = require('lib/models/Note.js');
|
||||
const { sprintf } = require('sprintf-js');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const Note = require('lib/models/Note.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const Note = require('lib/models/Note.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const { uuid } = require('lib/uuid.js');
|
||||
const uuid = require('lib/uuid').default;
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const { Logger } = require('lib/logger.js');
|
||||
const { shim } = require('lib/shim');
|
||||
const { _ } = require('lib/locale');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const Logger = require('lib/Logger').default;
|
||||
const shim = require('lib/shim').default;
|
||||
|
||||
class Command extends BaseCommand {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const { Database } = require('lib/database.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const { _ } = require('lib/locale');
|
||||
const { ReportService } = require('lib/services/report.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const { OneDriveApiNodeUtils } = require('lib/onedrive-api-node-utils.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const ResourceFetcher = require('lib/services/ResourceFetcher');
|
||||
const { Synchronizer } = require('lib/synchronizer.js');
|
||||
const Synchronizer = require('lib/Synchronizer').default;
|
||||
const { reg } = require('lib/registry.js');
|
||||
const { cliUtils } = require('./cli-utils.js');
|
||||
const md5 = require('md5');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
|
||||
const CommandDone = require('./command-done.js');
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const { _ } = require('lib/locale');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const { time } = require('lib/time-utils.js');
|
||||
const { Logger } = require('lib/logger.js');
|
||||
const Logger = require('lib/Logger').default;
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const { dirname } = require('lib/path-utils.js');
|
||||
const { FsDriverNode } = require('./fs-driver-node.js');
|
||||
|
||||
@@ -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.js')._;
|
||||
const _ = require('lib/locale')._;
|
||||
|
||||
class FolderListWidget extends ListWidget {
|
||||
constructor() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const Note = require('lib/models/Note.js');
|
||||
const TextWidget = require('tkwidgets/TextWidget.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
|
||||
class NoteWidget extends TextWidget {
|
||||
constructor() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { wrap } = require('lib/string-utils.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const { _ } = require('lib/locale');
|
||||
|
||||
const MAX_WIDTH = 78;
|
||||
const INDENT = ' ';
|
||||
|
||||
@@ -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.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const Revision = require('lib/models/Revision.js');
|
||||
const { Logger } = require('lib/logger.js');
|
||||
const Logger = require('lib/Logger').default;
|
||||
const { FsDriverNode } = require('lib/fs-driver-node.js');
|
||||
const { shimInit } = require('lib/shim-init-node.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const { FileApiDriverLocal } = require('lib/file-api-driver-local.js');
|
||||
const EncryptionService = require('lib/services/EncryptionService');
|
||||
const envFromArgs = require('lib/envFromArgs');
|
||||
|
||||
68
CliClient/app/services/plugins/PluginRunner.ts
Normal file
68
CliClient/app/services/plugins/PluginRunner.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -46,8 +46,14 @@ tasks.prepareTestBuild = {
|
||||
],
|
||||
});
|
||||
|
||||
await utils.copyDir(`${__dirname}/../ReactNativeClient/lib`, `${testBuildDir}/lib`);
|
||||
await utils.copyDir(`${__dirname}/../ReactNativeClient/locales`, `${testBuildDir}/locales`);
|
||||
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 fs.mkdirp(`${testBuildDir}/data`);
|
||||
},
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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.0.6\n"
|
||||
"X-Generator: Poedit 2.4.1\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 # suivit du nom d’une étiquette, ou @ "
|
||||
"suivit du nom d’un carnet."
|
||||
"Entrez le titre d’une note, ou entrez # suivi du nom d’une étiquette, ou @ "
|
||||
"suivi du nom d’un carnet."
|
||||
|
||||
#: ElectronClient/plugins/GotoAnything.min.js:486
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:20
|
||||
|
||||
@@ -15,6 +15,8 @@ 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 ""
|
||||
@@ -312,7 +314,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
|
||||
@@ -796,6 +798,8 @@ msgstr "キャンセル"
|
||||
msgid ""
|
||||
"The app is now going to close. Please relaunch it to complete the process."
|
||||
msgstr ""
|
||||
"まもなくアプリケーションは終了します。もう一度起動して処理を完了させてくださ"
|
||||
"い。"
|
||||
|
||||
#: ElectronClient/plugins/GotoAnything.min.js:446
|
||||
msgid ""
|
||||
@@ -1157,13 +1161,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"
|
||||
@@ -1274,7 +1278,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
|
||||
@@ -1289,12 +1293,11 @@ 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
|
||||
@@ -1317,9 +1320,8 @@ 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
|
||||
@@ -1327,7 +1329,6 @@ msgid "Close Window"
|
||||
msgstr "ウィンドウを閉じる"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:28
|
||||
#, fuzzy
|
||||
msgid "Preferences"
|
||||
msgstr "環境設定"
|
||||
|
||||
@@ -1338,13 +1339,15 @@ 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
|
||||
@@ -1358,11 +1361,13 @@ 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."
|
||||
@@ -2114,9 +2119,8 @@ msgid "Templates"
|
||||
msgstr "テンプレート"
|
||||
|
||||
#: ElectronClient/app.js:668
|
||||
#, fuzzy
|
||||
msgid "Export all"
|
||||
msgstr "エクスポート"
|
||||
msgstr "すべてをエクスポート"
|
||||
|
||||
#: ElectronClient/app.js:683
|
||||
#, javascript-format
|
||||
@@ -2215,7 +2219,7 @@ msgstr "不明なレベルID: %s"
|
||||
|
||||
#: ReactNativeClient/lib/SyncTargetAmazonS3.js:28
|
||||
msgid "AWS S3"
|
||||
msgstr ""
|
||||
msgstr "AWS S3"
|
||||
|
||||
#: ReactNativeClient/lib/SyncTargetDropbox.js:25
|
||||
msgid "Dropbox"
|
||||
@@ -2360,15 +2364,15 @@ msgstr "WevDAV パスワード"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:195
|
||||
msgid "AWS S3 bucket"
|
||||
msgstr ""
|
||||
msgstr "AWS S3 バケット"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:206
|
||||
msgid "AWS key"
|
||||
msgstr ""
|
||||
msgstr "AWS アクセスキーID"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:216
|
||||
msgid "AWS secret"
|
||||
msgstr ""
|
||||
msgstr "AWS シークレットアクセスキー"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:230
|
||||
msgid "Attachment download behaviour"
|
||||
@@ -2823,9 +2827,8 @@ msgid "Web Clipper"
|
||||
msgstr "Webクリッパー"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:1259
|
||||
#, fuzzy
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "キーバインド"
|
||||
msgstr "キーボードショートカット"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:1264
|
||||
msgid ""
|
||||
@@ -2980,6 +2983,8 @@ 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
|
||||
@@ -3024,8 +3029,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!"
|
||||
@@ -3102,7 +3107,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:"
|
||||
@@ -3151,10 +3156,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"
|
||||
@@ -3546,32 +3551,35 @@ msgstr "ノートをどのノートブックにインポートするのか指定
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:124
|
||||
#, javascript-format
|
||||
msgid "Error loading the keymap from file: %s"
|
||||
msgstr ""
|
||||
msgstr "キーマップ読み込みエラー(ファイル: %s)"
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:141
|
||||
#, javascript-format
|
||||
msgid "Error saving the keymap to file: %s"
|
||||
msgstr ""
|
||||
msgstr "キーマップ書き出しエラー(ファイル: %s)"
|
||||
|
||||
#: 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 ""
|
||||
msgstr "キーマップアイテム %s は %s が有効なコマンドでないため無効です。"
|
||||
|
||||
#: 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
|
||||
@@ -3579,11 +3587,13 @@ 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 ""
|
||||
msgstr "ショートカットキー \"%s\" は無効です。"
|
||||
|
||||
#: ReactNativeClient/lib/services/report.js:121
|
||||
msgid "Items that cannot be synchronised"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,9 +13,11 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.4\n"
|
||||
"X-Generator: Poedit 2.4.1\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 "
|
||||
"|| n%100>14) ? 1 : 2);\n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
|
||||
#: CliClient/app/command-cp.js:13
|
||||
msgid ""
|
||||
@@ -319,7 +321,7 @@ msgstr ""
|
||||
|
||||
#: CliClient/app/command-sync.js:35
|
||||
msgid "Upgrade the sync target to the latest version."
|
||||
msgstr ""
|
||||
msgstr "Aktualizuj cel synchronizacji do najnowszej wersji."
|
||||
|
||||
#: CliClient/app/command-sync.js:81 CliClient/app/command-sync.js:95
|
||||
#: ElectronClient/gui/OneDriveLoginScreen.min.js:40
|
||||
@@ -818,6 +820,7 @@ msgstr "Anuluj"
|
||||
msgid ""
|
||||
"The app is now going to close. Please relaunch it to complete the process."
|
||||
msgstr ""
|
||||
"Aplikacja zostanie teraz zamknięta. Uruchom ją ponownie aby ukończyć proces."
|
||||
|
||||
#: ElectronClient/plugins/GotoAnything.min.js:446
|
||||
msgid ""
|
||||
@@ -1179,13 +1182,13 @@ msgstr "Tworzenie nowego %s..."
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/NoteEditor.js:344
|
||||
msgid "The following attachments are being watched for changes:"
|
||||
msgstr ""
|
||||
msgstr "Następujące załączniki są obserwowane pod kątem zmian:"
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/NoteEditor.js:347
|
||||
msgid ""
|
||||
"The attachments will no longer be watched when you switch to a different "
|
||||
"note."
|
||||
msgstr ""
|
||||
msgstr "Załączniki nie będą obserwowane gdy przejdziesz do innej notatki."
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.js:25
|
||||
msgid "Select all"
|
||||
@@ -1296,7 +1299,7 @@ msgstr "Właściwośći notatki"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:62
|
||||
msgid "An unexpected error occured while importing the keymap!"
|
||||
msgstr ""
|
||||
msgstr "Wystąpił nieznany błąd podczas importu mapy klawiszy!"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:119
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:437
|
||||
@@ -1311,12 +1314,11 @@ msgstr "Zaimportuj"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:125
|
||||
msgid "Command"
|
||||
msgstr ""
|
||||
msgstr "Komenda"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:126
|
||||
#, fuzzy
|
||||
msgid "Keyboard Shortcut"
|
||||
msgstr "Tryb klawiatury"
|
||||
msgstr "Skrót klawiszowy"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:14
|
||||
#: ElectronClient/app.js:690
|
||||
@@ -1339,9 +1341,8 @@ msgid "Website and documentation"
|
||||
msgstr "Strona internetowa i dokumentacja"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:24
|
||||
#, fuzzy
|
||||
msgid "Hide Joplin"
|
||||
msgstr "O aplikacji Joplin"
|
||||
msgstr "Ukryj okno aplikacji"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:26
|
||||
#: ElectronClient/app.js:703
|
||||
@@ -1349,9 +1350,8 @@ msgid "Close Window"
|
||||
msgstr "Zamknij okno"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:28
|
||||
#, fuzzy
|
||||
msgid "Preferences"
|
||||
msgstr "Preferencje..."
|
||||
msgstr "Ustawienia"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:28
|
||||
#: ElectronClient/gui/Root.min.js:92 ElectronClient/app.js:572
|
||||
@@ -1360,13 +1360,15 @@ msgstr "Opcje"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:48
|
||||
msgid "Press the shortcut"
|
||||
msgstr ""
|
||||
msgstr "Naciśnij skrót klawiszowy"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:48
|
||||
msgid ""
|
||||
"Press the shortcut and then press ENTER. Or, press BACKSPACE to clear the "
|
||||
"shortcut."
|
||||
msgstr ""
|
||||
"Naciśnij skrót klawiszowy, a następnie ENTER aby potwierdzić. Naciśnij "
|
||||
"BACKSPACE aby wyczyścić skrót."
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:49
|
||||
#: ElectronClient/gui/EncryptionConfigScreen.min.js:95
|
||||
@@ -1380,11 +1382,13 @@ msgid ""
|
||||
"may take a few minutes to complete and the app needs to be restarted. To "
|
||||
"proceed please click on the link."
|
||||
msgstr ""
|
||||
"Cel synchronizacji wymaga aktualizacji zanim Joplin może się "
|
||||
"zsynchronizować. Ta operacja może zająć kilka minut po czym aplikacja będzie "
|
||||
"wymagać ponownego uruchomienia. Kliknij w link aby kontynuować."
|
||||
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:306
|
||||
#, fuzzy
|
||||
msgid "Restart and upgrade"
|
||||
msgstr "Klucze główne do aktualizacji"
|
||||
msgstr "Uruchom ponownie i aktualizuj"
|
||||
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:313
|
||||
msgid "Some items cannot be synchronised."
|
||||
@@ -1825,7 +1829,7 @@ msgstr ""
|
||||
"metodą."
|
||||
|
||||
#: ElectronClient/gui/EncryptionConfigScreen.min.js:185
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"In order to do so, your entire data set will have to be encrypted and "
|
||||
"synchronised, so it is best to run it overnight.\n"
|
||||
@@ -2144,9 +2148,8 @@ msgid "Templates"
|
||||
msgstr "Szablony"
|
||||
|
||||
#: ElectronClient/app.js:668
|
||||
#, fuzzy
|
||||
msgid "Export all"
|
||||
msgstr "Eksportuj"
|
||||
msgstr "Eksportuj wszystko"
|
||||
|
||||
#: ElectronClient/app.js:683
|
||||
#, javascript-format
|
||||
@@ -2178,13 +2181,12 @@ msgid "Zoom Out"
|
||||
msgstr "Pomniejsz"
|
||||
|
||||
#: ElectronClient/app.js:852
|
||||
#, fuzzy
|
||||
msgid "&Note"
|
||||
msgstr "Notatka"
|
||||
msgstr "&Notatka"
|
||||
|
||||
#: ElectronClient/app.js:861
|
||||
msgid "&Tools"
|
||||
msgstr "&Narzędzia"
|
||||
msgstr "N&arzędzia"
|
||||
|
||||
#: ElectronClient/app.js:865
|
||||
msgid "&Help"
|
||||
@@ -2360,7 +2362,7 @@ msgid ""
|
||||
"The target to synchonise to. Each sync target may have additional parameters "
|
||||
"which are named as `sync.NUM.NAME` (all documented below)."
|
||||
msgstr ""
|
||||
"Serwis z którym nastąpi snychronizacja. Każdy serwis może zawierać dodatkowe "
|
||||
"Serwis z którym nastąpi synchronizacja. Każdy serwis może zawierać dodatkowe "
|
||||
"parametry, które są nazwane jako `sync.NUM.NAME` (udokumentowane poniżej)."
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:110
|
||||
@@ -2415,8 +2417,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"W trybie \"Ręczny\", załączniki zostaną pobrane po naciśnięciu.W trybie "
|
||||
"\"Automatyczny\", załączniki zostaną pobrane przy otwieraniu notatki. W "
|
||||
"trybie \"Zawsze\", wszystkie załączniki zostaną pobrane bez względu "
|
||||
"naotwarcie notatki."
|
||||
"trybie \"Zawsze\", wszystkie załączniki zostaną pobrane bez względu na "
|
||||
"otwarcie notatki."
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:234
|
||||
msgid "Always"
|
||||
@@ -2452,7 +2454,7 @@ msgstr "Motyw"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:326
|
||||
msgid "Automatically switch theme to match system theme"
|
||||
msgstr "Automatycznie dopasyj motyw do motywu systemowego"
|
||||
msgstr "Automatycznie dopasuj motyw do motywu systemowego"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:338
|
||||
msgid "Preferred light theme"
|
||||
@@ -2460,7 +2462,7 @@ msgstr "Preferuj jasny motyw"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:352
|
||||
msgid "Preferred dark theme"
|
||||
msgstr "Preferuj ciemny motyw"
|
||||
msgstr "Preferuj ciemny motyw"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:357
|
||||
msgid "Show note counts"
|
||||
@@ -2537,7 +2539,7 @@ msgstr "Aktywuj składnię typografu"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:469
|
||||
msgid "Enable math expressions"
|
||||
msgstr "Atywuj wyrażenia matematyczne"
|
||||
msgstr "Aktywuj wyrażenia matematyczne"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:470
|
||||
msgid "Enable Fountain syntax support"
|
||||
@@ -2557,7 +2559,7 @@ msgstr "Aktywuj stopki"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:475
|
||||
msgid "Enable table of contents extension"
|
||||
msgstr "Aktywuj rozszerenie dla tabeli zawartości"
|
||||
msgstr "Aktywuj rozszerzenie dla tabeli zawartości"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:476
|
||||
msgid "Enable ~sub~ syntax"
|
||||
@@ -2569,7 +2571,7 @@ msgstr "Aktywuj składnię ^sup^"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:478
|
||||
msgid "Enable deflist syntax"
|
||||
msgstr "Aktywuj skladnię składnię deflist"
|
||||
msgstr "Aktywuj składnię składnię deflist"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:479
|
||||
msgid "Enable abbreviation syntax"
|
||||
@@ -2607,7 +2609,7 @@ msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:500
|
||||
msgid "Start application minimised in the tray icon"
|
||||
msgstr "Uruchom aplikację zminmalizowaną w zasobniku systemowym"
|
||||
msgstr "Uruchom aplikację zminimalizowaną w zasobniku systemowym"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:519
|
||||
msgid "Editor font size"
|
||||
@@ -2723,7 +2725,7 @@ msgstr "Pionowo"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:639
|
||||
msgid "Landscape"
|
||||
msgstr "Poziomio"
|
||||
msgstr "Poziomo"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:650
|
||||
msgid "Keyboard Mode"
|
||||
@@ -2743,7 +2745,7 @@ msgstr "Vim"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:670
|
||||
msgid "Custom TLS certificates"
|
||||
msgstr "Niestandardowe ceryfikaty TLS"
|
||||
msgstr "Niestandardowe certyfikaty TLS"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:671
|
||||
msgid ""
|
||||
@@ -2753,9 +2755,9 @@ msgid ""
|
||||
"changes before clicking on \"Check synchronisation configuration\"."
|
||||
msgstr ""
|
||||
"Wykaz ścieżek katalogów podzielony przecinkami z których będą ładowane "
|
||||
"ceryfikaty, lub ścieżka do odrębnych plików ceryfikacyjnych. Na przykład: /"
|
||||
"my/cert_dir, /other/custom.pem. Jeżeli zostaną zmienione ustawienia TLS, "
|
||||
"będzie wymagane zapisanie zmian przez naciśnięciem na \"Sprawdź konfigurację "
|
||||
"certyfikaty, lub ścieżka do odrębnych plików certyfikatów. Na przykład: /my/"
|
||||
"cert_dir, /other/custom.pem. Jeżeli zostaną zmienione ustawienia TLS, będzie "
|
||||
"wymagane zapisanie zmian przez naciśnięciem na \"Sprawdź konfigurację "
|
||||
"synchronizacji\"."
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:683
|
||||
@@ -2862,9 +2864,8 @@ msgid "Web Clipper"
|
||||
msgstr "Web clipper"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:1259
|
||||
#, fuzzy
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "Tryb klawiatury"
|
||||
msgstr "Skróty klawiaturowe"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:1264
|
||||
msgid ""
|
||||
@@ -2876,13 +2877,13 @@ msgid ""
|
||||
"formatting. It is indicated below which plugins are compatible or not with "
|
||||
"the WYSIWYG editor."
|
||||
msgstr ""
|
||||
"Te wtyczki usprawniają wyświtlanie Markdownu. Miej na uwadze, że mimo, że te "
|
||||
"znaczniki mogą być przydatne, to nie są one częścią standardowego Markdownu "
|
||||
"i z uwagi na to większość z nich będzie działała wyłącznie w Joplinie. "
|
||||
"Dodatkowo, część z nich jest *niekompatybilna* z edytorem WYSIWYG. Jeśli "
|
||||
"otworzysz notatkę używającą tego formatowania w tym edytorze, utracisz to "
|
||||
"formatowanie. Poniżej jest widoczne które pluginy są kompatybilne z edytorem "
|
||||
"WYSIWYG."
|
||||
"Te wtyczki usprawniają wyświetlanie Markdownu. Miej na uwadze, że mimo, że "
|
||||
"te znaczniki mogą być przydatne, to nie są one częścią standardowego "
|
||||
"Markdownu i z uwagi na to większość z nich będzie działała wyłącznie w "
|
||||
"Joplinie. Dodatkowo, część z nich jest *niekompatybilna* z edytorem WYSIWYG. "
|
||||
"Jeśli otworzysz notatkę używającą tego formatowania w tym edytorze, utracisz "
|
||||
"to formatowanie. Poniżej jest widoczne które pluginy są kompatybilne z "
|
||||
"edytorem WYSIWYG."
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:1265
|
||||
#, javascript-format
|
||||
@@ -2990,15 +2991,15 @@ msgstr "Potwierdź"
|
||||
|
||||
#: ReactNativeClient/lib/components/CameraView.js:180
|
||||
msgid "Permission to use camera"
|
||||
msgstr "Uprawenie do użytkowania kamery"
|
||||
msgstr "Uprawienie do użytkowania kamery"
|
||||
|
||||
#: ReactNativeClient/lib/components/CameraView.js:181
|
||||
msgid "Your permission to use your camera is required."
|
||||
msgstr "Wymagane uprawenienie do użytkowania kamery."
|
||||
msgstr "Wymagane uprawnienie do użytkowania kamery."
|
||||
|
||||
#: ReactNativeClient/lib/components/screen-header.js:185
|
||||
msgid "Delete these notes?"
|
||||
msgstr "Usunąć notatki?"
|
||||
msgstr "Usunąć te notatki?"
|
||||
|
||||
#: ReactNativeClient/lib/components/screen-header.js:392
|
||||
msgid "Move to notebook..."
|
||||
@@ -3007,7 +3008,7 @@ msgstr "Przenieś do notatnika..."
|
||||
#: ReactNativeClient/lib/components/screen-header.js:433
|
||||
#, javascript-format
|
||||
msgid "Move %d notes to notebook \"%s\"?"
|
||||
msgstr "Przenieś %d notatek do notatnika \"%s\"?"
|
||||
msgstr "Przenieść %d notatek do notatnika \"%s\"?"
|
||||
|
||||
#: ReactNativeClient/lib/components/screen-header.js:451
|
||||
msgid "Press to set the decryption password."
|
||||
@@ -3020,6 +3021,7 @@ msgstr "Niektóre przedmioty nie mogą być zsynchronizowane."
|
||||
#: ReactNativeClient/lib/components/screen-header.js:453
|
||||
msgid "The sync target needs to be upgraded. Press this banner to proceed."
|
||||
msgstr ""
|
||||
"Cel aktualizacji wymaga aktualizacji. Kliknij w ten baner aby kontynuować."
|
||||
|
||||
#: ReactNativeClient/lib/components/side-menu-content.js:126
|
||||
#, javascript-format
|
||||
@@ -3142,7 +3144,7 @@ msgstr "Odśwież"
|
||||
|
||||
#: ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js:42
|
||||
msgid "Sync Target Upgrade"
|
||||
msgstr ""
|
||||
msgstr "Aktualizacja celu synchronizacji"
|
||||
|
||||
#: ReactNativeClient/lib/components/screens/NoteTagsDialog.js:163
|
||||
msgid "New tags:"
|
||||
@@ -3193,7 +3195,7 @@ msgid ""
|
||||
"the data! To enable encryption, please enter your password below."
|
||||
msgstr ""
|
||||
"Aktywowanie szyfrowania oznacza, że *wszystkie* Twoje notatki i załączniki "
|
||||
"będą resynchronizowane i wysłane zaszyfrowane do serwisu synchonizacji. Nie "
|
||||
"będą re-synchronizowane i wysłane zaszyfrowane do celu synchronizacji. Nie "
|
||||
"utrać hasła, jako że, w celu zapewnienia bezpieczeństwa, będzie to *jedyna* "
|
||||
"droga do deszyfrowania danych! Aby aktywować szyfrowanie, wprowadź hasło "
|
||||
"poniżej."
|
||||
@@ -3214,11 +3216,11 @@ msgid ""
|
||||
msgstr ""
|
||||
"Klucze główne z tymi ID zostaną użyte do szyfrowania niektórych obiektów, "
|
||||
"jednakże aplikacja aktualnie nie ma do nich dostępu. Prawdopodobnie zostaną "
|
||||
"pobrane przy synchonizacji."
|
||||
"pobrane przy synchronizacji."
|
||||
|
||||
#: ReactNativeClient/lib/components/screens/encryption-config.js:258
|
||||
msgid "Disable encryption"
|
||||
msgstr "Deaktywuj szyfrowanie"
|
||||
msgstr "Dezaktywuj szyfrowanie"
|
||||
|
||||
#: ReactNativeClient/lib/components/screens/encryption-config.js:258
|
||||
msgid "Enable encryption"
|
||||
@@ -3467,7 +3469,7 @@ msgstr "Utworzono lokalne obiekty: %d."
|
||||
#: ReactNativeClient/lib/synchronizer.js:105
|
||||
#, javascript-format
|
||||
msgid "Updated local items: %d."
|
||||
msgstr "Zaaktualizowano lokalne obiekty: %d."
|
||||
msgstr "Zaktualizowano lokalne obiekty: %d."
|
||||
|
||||
#: ReactNativeClient/lib/synchronizer.js:106
|
||||
#, javascript-format
|
||||
@@ -3477,7 +3479,7 @@ msgstr "Utworzono zdalne obiekty: %d."
|
||||
#: ReactNativeClient/lib/synchronizer.js:107
|
||||
#, javascript-format
|
||||
msgid "Updated remote items: %d."
|
||||
msgstr "Zaaktualizowano zdalne obiekty: %d."
|
||||
msgstr "Zaktualizowano zdalne obiekty: %d."
|
||||
|
||||
#: ReactNativeClient/lib/synchronizer.js:108
|
||||
#, javascript-format
|
||||
@@ -3577,7 +3579,7 @@ msgstr "Wersja profilu: %s"
|
||||
#: ReactNativeClient/lib/versionInfo.js:23
|
||||
#, javascript-format
|
||||
msgid "Keychain Supported: %s"
|
||||
msgstr ""
|
||||
msgstr "Wspierany menadżer kluczy: %s"
|
||||
|
||||
#: ReactNativeClient/lib/services/InteropService_Exporter_Jex.js:29
|
||||
msgid "There is no data to export."
|
||||
@@ -3594,32 +3596,38 @@ msgstr "Proszę określić notatnik do którego będą zaimportowane notatki."
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:124
|
||||
#, javascript-format
|
||||
msgid "Error loading the keymap from file: %s"
|
||||
msgstr ""
|
||||
msgstr "Błąd podczas ładowania mapy klawiszy z pliku: %s"
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:141
|
||||
#, javascript-format
|
||||
msgid "Error saving the keymap to file: %s"
|
||||
msgstr ""
|
||||
msgstr "Błąd podczas zapisu mapy klawiszy do pliku: %s"
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:204
|
||||
#, javascript-format
|
||||
msgid "Keymap item %s is missing the required \"command\" property."
|
||||
msgstr ""
|
||||
"Element skrótu klawiszowego %s nie zawiera wymaganego pola: \"command\"."
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:207
|
||||
#, javascript-format
|
||||
msgid "Keymap item %s is invalid because %s is not a valid command."
|
||||
msgstr ""
|
||||
"Element skrótu klawiszowego %s jest niepoprawny ponieważ %s nie jest "
|
||||
"prawidłową komendą."
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:210
|
||||
#, javascript-format
|
||||
msgid "Keymap item %s is missing the required \"accelerator\" property."
|
||||
msgstr ""
|
||||
"Element skrótu klawiszowego %s nie zawiera wymaganego pola: \"accelerator\"."
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:217
|
||||
#, javascript-format
|
||||
msgid "Keymap item %s is invalid because %s is not a valid accelerator."
|
||||
msgstr ""
|
||||
"Element skrótu klawiszowego %s jest niepoprawny ponieważ %s nie jest "
|
||||
"prawidłową kombinacją klawiszy."
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:235
|
||||
#, javascript-format
|
||||
@@ -3627,11 +3635,13 @@ msgid ""
|
||||
"Accelerator \"%s\" is used for \"%s\" and \"%s\" commands. This may lead to "
|
||||
"unexpected behaviour."
|
||||
msgstr ""
|
||||
"Skrót klawiszowy \"%s\" jest już używany w komendach \"%s\" i \"%s\". Może "
|
||||
"to powodować nieoczekiwane zachowanie."
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:260
|
||||
#, javascript-format
|
||||
msgid "Accelerator \"%s\" is not valid."
|
||||
msgstr ""
|
||||
msgstr "Skrót klawiszowy \"%s\" nie jest prawidłowy."
|
||||
|
||||
#: ReactNativeClient/lib/services/report.js:121
|
||||
msgid "Items that cannot be synchronised"
|
||||
|
||||
@@ -14,7 +14,9 @@ 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.3.1\n"
|
||||
"X-Generator: Poedit 2.4.1\n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
|
||||
#: CliClient/app/command-cp.js:13
|
||||
msgid ""
|
||||
@@ -319,7 +321,7 @@ msgstr ""
|
||||
|
||||
#: CliClient/app/command-sync.js:35
|
||||
msgid "Upgrade the sync target to the latest version."
|
||||
msgstr ""
|
||||
msgstr "Senkronizasyon hedefini en son sürüme yükseltin"
|
||||
|
||||
#: CliClient/app/command-sync.js:81 CliClient/app/command-sync.js:95
|
||||
#: ElectronClient/gui/OneDriveLoginScreen.min.js:40
|
||||
@@ -813,6 +815,8 @@ 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 ""
|
||||
@@ -1173,13 +1177,13 @@ msgstr "Yeni %s oluşturuluyor..."
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/NoteEditor.js:344
|
||||
msgid "The following attachments are being watched for changes:"
|
||||
msgstr ""
|
||||
msgstr "Şu ek dosyaları değişiklikler için izlenmekte:"
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/NoteEditor.js:347
|
||||
msgid ""
|
||||
"The attachments will no longer be watched when you switch to a different "
|
||||
"note."
|
||||
msgstr ""
|
||||
msgstr "Eğer başka bir not'a geçerseniz ek dosyalar artık izlenmeyecek."
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.js:25
|
||||
msgid "Select all"
|
||||
@@ -1290,7 +1294,7 @@ msgstr "Not özellikleri"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:62
|
||||
msgid "An unexpected error occured while importing the keymap!"
|
||||
msgstr ""
|
||||
msgstr "Tuş dizimini içe aktarırken bir hata oluştu!"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:119
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:437
|
||||
@@ -1305,12 +1309,11 @@ msgstr "İçe aktar"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:125
|
||||
msgid "Command"
|
||||
msgstr ""
|
||||
msgstr "Komut"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:126
|
||||
#, fuzzy
|
||||
msgid "Keyboard Shortcut"
|
||||
msgstr "Klavye modu"
|
||||
msgstr "Klavye Kısayolu"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:14
|
||||
#: ElectronClient/app.js:690
|
||||
@@ -1333,9 +1336,8 @@ msgid "Website and documentation"
|
||||
msgstr "Web sitesi ve dökümanlar"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:24
|
||||
#, fuzzy
|
||||
msgid "Hide Joplin"
|
||||
msgstr "Joplin hakkında"
|
||||
msgstr "Joplin'i Gizle"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:26
|
||||
#: ElectronClient/app.js:703
|
||||
@@ -1343,9 +1345,8 @@ 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
|
||||
@@ -1354,13 +1355,15 @@ msgstr "Seçenekler"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:48
|
||||
msgid "Press the shortcut"
|
||||
msgstr ""
|
||||
msgstr "Kısayolu girin"
|
||||
|
||||
#: 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
|
||||
@@ -1374,11 +1377,14 @@ 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 "Ana anahtarların güncellenmesi lazım"
|
||||
msgstr "Yeniden başlat ve güncelle"
|
||||
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:313
|
||||
msgid "Some items cannot be synchronised."
|
||||
@@ -2138,9 +2144,8 @@ msgid "Templates"
|
||||
msgstr "Şablonlar"
|
||||
|
||||
#: ElectronClient/app.js:668
|
||||
#, fuzzy
|
||||
msgid "Export all"
|
||||
msgstr "Dışa aktar"
|
||||
msgstr "Tümünü dışa aktar"
|
||||
|
||||
#: ElectronClient/app.js:683
|
||||
#, javascript-format
|
||||
@@ -2241,7 +2246,7 @@ msgstr "Bilinmeyen ID seviyesi: %s"
|
||||
|
||||
#: ReactNativeClient/lib/SyncTargetAmazonS3.js:28
|
||||
msgid "AWS S3"
|
||||
msgstr ""
|
||||
msgstr "AWS S3"
|
||||
|
||||
#: ReactNativeClient/lib/SyncTargetDropbox.js:25
|
||||
msgid "Dropbox"
|
||||
@@ -2384,15 +2389,15 @@ msgstr "WebDAV şifresi"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:195
|
||||
msgid "AWS S3 bucket"
|
||||
msgstr ""
|
||||
msgstr "AWS S3 deposu"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:206
|
||||
msgid "AWS key"
|
||||
msgstr ""
|
||||
msgstr "AWS anahtarı"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:216
|
||||
msgid "AWS secret"
|
||||
msgstr ""
|
||||
msgstr "AWS gizli anahtarı"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:230
|
||||
msgid "Attachment download behaviour"
|
||||
@@ -2850,9 +2855,8 @@ msgid "Web Clipper"
|
||||
msgstr "Web Alıntılayıcısı"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:1259
|
||||
#, fuzzy
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "Klavye modu"
|
||||
msgstr "Klavye Kısayolları"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:1264
|
||||
msgid ""
|
||||
@@ -3008,6 +3012,8 @@ 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
|
||||
@@ -3129,7 +3135,7 @@ msgstr "Yenile"
|
||||
|
||||
#: ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js:42
|
||||
msgid "Sync Target Upgrade"
|
||||
msgstr ""
|
||||
msgstr "Senkronizasyon Hedefi Güncellemesi"
|
||||
|
||||
#: ReactNativeClient/lib/components/screens/NoteTagsDialog.js:163
|
||||
msgid "New tags:"
|
||||
@@ -3578,32 +3584,37 @@ 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 ""
|
||||
msgstr "%s dosyasından tuş haritası yüklenemedi"
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:141
|
||||
#, javascript-format
|
||||
msgid "Error saving the keymap to file: %s"
|
||||
msgstr ""
|
||||
msgstr "%s dosyasına tuş haritası kaydedilemedi"
|
||||
|
||||
#: 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 ""
|
||||
msgstr "%s tuş haritası geçersizdir, çünkü %s geçerli bir komut değildir."
|
||||
|
||||
#: 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
|
||||
@@ -3611,11 +3622,13 @@ 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 ""
|
||||
msgstr "Kısayol \"%s\" geçersiz."
|
||||
|
||||
#: ReactNativeClient/lib/services/report.js:121
|
||||
msgid "Items that cannot be synchronised"
|
||||
@@ -3949,7 +3962,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."
|
||||
|
||||
40
CliClient/package-lock.json
generated
40
CliClient/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "joplin",
|
||||
"version": "1.0.168",
|
||||
"version": "1.3.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -606,6 +606,11 @@
|
||||
"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",
|
||||
@@ -4344,6 +4349,11 @@
|
||||
"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",
|
||||
@@ -5250,6 +5260,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"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",
|
||||
@@ -5610,6 +5625,11 @@
|
||||
"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",
|
||||
@@ -5880,6 +5900,11 @@
|
||||
"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",
|
||||
@@ -6742,11 +6767,6 @@
|
||||
"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",
|
||||
@@ -6849,14 +6869,6 @@
|
||||
"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",
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
],
|
||||
"owner": "Laurent Cozic"
|
||||
},
|
||||
"version": "1.0.168",
|
||||
"version": "1.3.0",
|
||||
"bin": {
|
||||
"joplin": "./main.js"
|
||||
},
|
||||
@@ -41,6 +41,7 @@
|
||||
"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",
|
||||
@@ -83,6 +84,7 @@
|
||||
"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",
|
||||
@@ -91,13 +93,16 @@
|
||||
"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",
|
||||
@@ -109,7 +114,6 @@
|
||||
"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",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
require('app-module-path').addPath(__dirname);
|
||||
|
||||
const { asyncTest, setupDatabaseAndSynchronizer, switchClient } = require('test-utils.js');
|
||||
const { shim } = require('lib/shim');
|
||||
const shim = require('lib/shim').default;
|
||||
const { enexXmlToHtml } = require('lib/import-enex-html-gen.js');
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
|
||||
@@ -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');
|
||||
const shim = require('lib/shim').default;
|
||||
const { enexXmlToMd } = require('lib/import-enex-md-gen.js');
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
|
||||
@@ -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');
|
||||
const shim = require('lib/shim').default;
|
||||
const HtmlToHtml = require('lib/joplin-renderer/HtmlToHtml');
|
||||
const { enexXmlToMd } = require('lib/import-enex-md-gen.js');
|
||||
|
||||
|
||||
@@ -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');
|
||||
const shim = require('lib/shim').default;
|
||||
const HtmlToMd = require('lib/HtmlToMd');
|
||||
const { enexXmlToMd } = require('lib/import-enex-md-gen.js');
|
||||
|
||||
|
||||
@@ -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');
|
||||
const shim = require('lib/shim').default;
|
||||
const MdToHtml = require('lib/joplin-renderer/MdToHtml');
|
||||
const { enexXmlToMd } = require('lib/import-enex-md-gen.js');
|
||||
const { themeStyle } = require('lib/theme');
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const mdImporterService = require('lib/services/InteropService_Importer_Md');
|
||||
const mdImporterService = require('lib/services/interop/InteropService_Importer_Md').default;
|
||||
const Note = require('lib/models/Note.js');
|
||||
const { setupDatabaseAndSynchronizer, switchClient } = require('test-utils.js');
|
||||
|
||||
|
||||
@@ -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.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const ArrayUtils = require('lib/ArrayUtils.js');
|
||||
const { shim } = require('lib/shim');
|
||||
const shim = require('lib/shim').default;
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
|
||||
121
CliClient/tests/eventManager.js
Normal file
121
CliClient/tests/eventManager.js
Normal file
@@ -0,0 +1,121 @@
|
||||
'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);
|
||||
}));
|
||||
|
||||
});
|
||||
@@ -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.js');
|
||||
const uuid = require('lib/uuid').default;
|
||||
const Note = require('lib/models/Note.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
|
||||
|
||||
@@ -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.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
|
||||
@@ -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.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
|
||||
@@ -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.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
require('app-module-path').addPath(__dirname);
|
||||
|
||||
const { uuid } = require('lib/uuid.js');
|
||||
const uuid = require('lib/uuid').default;
|
||||
const { time } = require('lib/time-utils.js');
|
||||
const { asyncTest, sleep, fileApi, fileContentEqual, checkThrowAsync } = require('test-utils.js');
|
||||
const { shim } = require('lib/shim.js');
|
||||
const shim = require('lib/shim').default;
|
||||
const fs = require('fs-extra');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
require('app-module-path').addPath(__dirname);
|
||||
|
||||
const { asyncTest } = require('test-utils.js');
|
||||
const markdownUtils = require('lib/markdownUtils.js');
|
||||
const markdownUtils = require('lib/markdownUtils').default;
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
|
||||
@@ -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');
|
||||
const shim = require('lib/shim').default;
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
|
||||
@@ -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');
|
||||
const shim = require('lib/shim').default;
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
|
||||
@@ -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');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const ItemChange = require('lib/models/ItemChange');
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
|
||||
@@ -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.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const ArrayUtils = require('lib/ArrayUtils.js');
|
||||
const { shim } = require('lib/shim');
|
||||
const shim = require('lib/shim').default;
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
|
||||
@@ -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.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const ArrayUtils = require('lib/ArrayUtils.js');
|
||||
const { shim } = require('lib/shim');
|
||||
const shim = require('lib/shim').default;
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
|
||||
@@ -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');
|
||||
const shim = require('lib/shim').default;
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
|
||||
@@ -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');
|
||||
const shim = require('lib/shim').default;
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/* 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);
|
||||
}));
|
||||
|
||||
});
|
||||
135
CliClient/tests/models_Setting.ts
Normal file
135
CliClient/tests/models_Setting.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
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');
|
||||
}));
|
||||
});
|
||||
@@ -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');
|
||||
const shim = require('lib/shim').default;
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
|
||||
@@ -5,7 +5,8 @@ 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, defaultState, stateUtils, MAX_HISTORY } = require('lib/reducer.js');
|
||||
const reducer = require('lib/reducer').default;
|
||||
const { defaultState, stateUtils, MAX_HISTORY } = require('lib/reducer');
|
||||
|
||||
function initTestState(folders, selectedFolderIndex, notes, selectedNoteIndexes, tags = null, selectedTagIndex = null) {
|
||||
let state = defaultState;
|
||||
@@ -87,7 +88,7 @@ function getIds(items, indexes = null) {
|
||||
|
||||
let insideBeforeEach = false;
|
||||
|
||||
describe('Reducer', function() {
|
||||
describe('reducer', function() {
|
||||
|
||||
beforeEach(async (done) => {
|
||||
insideBeforeEach = true;
|
||||
|
||||
58
CliClient/tests/services/plugins/sandboxProxy.ts
Normal file
58
CliClient/tests/services/plugins/sandboxProxy.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
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');
|
||||
}));
|
||||
|
||||
});
|
||||
278
CliClient/tests/services_CommandService.ts
Normal file
278
CliClient/tests/services_CommandService.ts
Normal file
@@ -0,0 +1,278 @@
|
||||
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');
|
||||
}));
|
||||
|
||||
});
|
||||
@@ -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.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const BaseItem = require('lib/models/BaseItem.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const MasterKey = require('lib/models/MasterKey');
|
||||
@@ -289,35 +289,4 @@ 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');
|
||||
// }));
|
||||
|
||||
});
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import InteropService from 'lib/services/interop/InteropService';
|
||||
import { CustomExportContext, CustomImportContext, Module, ModuleType } from 'lib/services/interop/types';
|
||||
import shim from 'lib/shim';
|
||||
|
||||
require('app-module-path').addPath(__dirname);
|
||||
|
||||
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 { asyncTest, fileContentEqual, setupDatabaseAndSynchronizer, switchClient, checkThrowAsync } = require('test-utils.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);
|
||||
@@ -23,7 +20,7 @@ function exportDir() {
|
||||
return `${__dirname}/export`;
|
||||
}
|
||||
|
||||
function fieldsEqual(model1, model2, fieldNames) {
|
||||
function fieldsEqual(model1:any, model2:any, fieldNames:string[]) {
|
||||
for (let i = 0; i < fieldNames.length; i++) {
|
||||
const f = fieldNames[i];
|
||||
expect(model1[f]).toBe(model2[f], `For key ${f}`);
|
||||
@@ -43,7 +40,7 @@ describe('services_InteropService', function() {
|
||||
});
|
||||
|
||||
it('should export and import folders', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
folder1 = await Folder.load(folder1.id);
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
@@ -78,7 +75,7 @@ describe('services_InteropService', function() {
|
||||
}));
|
||||
|
||||
it('should import folders and de-duplicate titles when needed', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
const folder1 = await Folder.save({ title: 'folder' });
|
||||
const folder2 = await Folder.save({ title: 'folder' });
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
@@ -90,15 +87,15 @@ describe('services_InteropService', function() {
|
||||
await service.import({ path: filePath });
|
||||
|
||||
const allFolders = await Folder.all();
|
||||
expect(allFolders.map(f => f.title).sort().join(' - ')).toBe('folder - folder (1)');
|
||||
expect(allFolders.map((f:any) => f.title).sort().join(' - ')).toBe('folder - folder (1)');
|
||||
}));
|
||||
|
||||
it('should import folders, and only de-duplicate titles when needed', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
const folder2 = await Folder.save({ title: 'folder2' });
|
||||
const sub1 = await Folder.save({ title: 'Sub', parent_id: folder1.id });
|
||||
const sub2 = await Folder.save({ title: 'Sub', parent_id: folder2.id });
|
||||
await Folder.save({ title: 'Sub', parent_id: folder1.id });
|
||||
await Folder.save({ title: 'Sub', parent_id: folder2.id });
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
await service.export({ path: filePath });
|
||||
|
||||
@@ -117,7 +114,7 @@ describe('services_InteropService', function() {
|
||||
}));
|
||||
|
||||
it('should export and import folders and notes', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
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);
|
||||
@@ -156,7 +153,7 @@ describe('services_InteropService', function() {
|
||||
}));
|
||||
|
||||
it('should export and import notes to specific folder', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
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);
|
||||
@@ -175,7 +172,7 @@ describe('services_InteropService', function() {
|
||||
}));
|
||||
|
||||
it('should export and import tags', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
const note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
@@ -215,7 +212,7 @@ describe('services_InteropService', function() {
|
||||
}));
|
||||
|
||||
it('should export and import resources', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
@@ -251,7 +248,7 @@ describe('services_InteropService', function() {
|
||||
}));
|
||||
|
||||
it('should export and import single notes', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
const note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
@@ -271,7 +268,7 @@ describe('services_InteropService', function() {
|
||||
}));
|
||||
|
||||
it('should export and import single folders', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
const note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
@@ -292,7 +289,7 @@ describe('services_InteropService', function() {
|
||||
|
||||
it('should export and import folder and its sub-folders', asyncTest(async () => {
|
||||
|
||||
const service = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
const folder2 = await Folder.save({ title: 'folder2', parent_id: folder1.id });
|
||||
@@ -326,7 +323,7 @@ describe('services_InteropService', function() {
|
||||
}));
|
||||
|
||||
it('should export and import links to notes', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
const note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
@@ -349,43 +346,21 @@ 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 = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
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);
|
||||
let note12 = await Note.save({ title: 'title note12', parent_id: folder1.id });
|
||||
note12 = await Note.load(note12.id);
|
||||
const note12 = await Note.save({ title: 'title note12', parent_id: folder1.id });
|
||||
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);
|
||||
|
||||
let folder3 = await Folder.save({ title: 'folder3', parent_id: folder1.id });
|
||||
folder3 = await Folder.load(folder2.id);
|
||||
await Folder.save({ title: 'folder3', parent_id: folder1.id });
|
||||
await Folder.load(folder2.id);
|
||||
|
||||
const outDir = exportDir();
|
||||
|
||||
@@ -401,16 +376,16 @@ describe('services_InteropService', function() {
|
||||
}));
|
||||
|
||||
it('should export MD with unicode filenames', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
const folder2 = await Folder.save({ title: 'ジョプリン' });
|
||||
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 });
|
||||
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 outDir = exportDir();
|
||||
|
||||
@@ -430,7 +405,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 = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
|
||||
await service.export({
|
||||
path: exportDir(),
|
||||
@@ -454,7 +429,7 @@ describe('services_InteropService', function() {
|
||||
|
||||
await Folder.save({ title: 'orphan', parent_id: '0c5bbd8a1b5a48189484a412a7e534cc' });
|
||||
|
||||
const service = new InteropService();
|
||||
const service = InteropService.instance();
|
||||
|
||||
const result = await service.export({
|
||||
path: exportDir(),
|
||||
@@ -464,4 +439,99 @@ 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);
|
||||
}));
|
||||
|
||||
|
||||
});
|
||||
@@ -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/InteropService_Exporter_Md.js');
|
||||
const InteropService_Exporter_Md = require('lib/services/interop/InteropService_Exporter_Md').default;
|
||||
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.js');
|
||||
const shim = require('lib/shim').default;
|
||||
|
||||
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, folder1);
|
||||
await exporter.processItem(Folder, folder2);
|
||||
await exporter.processItem(Folder.modelType(), folder1);
|
||||
await exporter.processItem(Folder.modelType(), 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, folder1);
|
||||
await exporter.processItem(Folder.modelType(), 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, folder1);
|
||||
await exporter.processItem(Folder.modelType(), 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, folder2);
|
||||
await exporter.processItem(Folder, folder3);
|
||||
await exporter.processItem(Folder.modelType(), folder2);
|
||||
await exporter.processItem(Folder.modelType(), folder3);
|
||||
await exporter.prepareForProcessingItemType(BaseModel.TYPE_NOTE, itemsToExport);
|
||||
await exporter.processItem(Note, note2);
|
||||
await exporter.processItem(Note.modelType(), 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, note1);
|
||||
await exporter.processItem(Note, note2);
|
||||
await exporter.processItem(Note, note3);
|
||||
await exporter.processItem(Note.modelType(), note1);
|
||||
await exporter.processItem(Note.modelType(), note2);
|
||||
await exporter.processItem(Note.modelType(), 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, folder1);
|
||||
await exporter.processItem(Folder, folder2);
|
||||
await exporter.processItem(Folder.modelType(), folder1);
|
||||
await exporter.processItem(Folder.modelType(), 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, note1);
|
||||
await exporter.processItem(Note, note2);
|
||||
await exporter.processItem(Note.modelType(), note1);
|
||||
await exporter.processItem(Note.modelType(), 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, folder1);
|
||||
await exporter.processItem(Folder, folder2);
|
||||
await exporter.processItem(Folder, folder3);
|
||||
await exporter.processItem(Folder.modelType(), folder1);
|
||||
await exporter.processItem(Folder.modelType(), folder2);
|
||||
await exporter.processItem(Folder.modelType(), folder3);
|
||||
await exporter.prepareForProcessingItemType(BaseModel.TYPE_NOTE, itemsToExport);
|
||||
await exporter.processItem(Note, note1);
|
||||
await exporter.processItem(Note, note2);
|
||||
await exporter.processItem(Note, note3);
|
||||
await exporter.processItem(Note.modelType(), note1);
|
||||
await exporter.processItem(Note.modelType(), note2);
|
||||
await exporter.processItem(Note.modelType(), 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, folder1);
|
||||
await exporter.processItem(Folder.modelType(), folder1);
|
||||
await exporter.prepareForProcessingItemType(BaseModel.TYPE_NOTE, itemsToExport);
|
||||
await exporter.processItem(Note, note1);
|
||||
await exporter.processItem(Note, note2);
|
||||
await exporter.processItem(Note.modelType(), note1);
|
||||
await exporter.processItem(Note.modelType(), 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');
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
require('app-module-path').addPath(__dirname);
|
||||
|
||||
const { tempFilePath } = require('test-utils.js');
|
||||
const KeymapService = require('lib/services/KeymapService').default;
|
||||
const keymapService = KeymapService.instance();
|
||||
|
||||
@@ -76,6 +77,31 @@ 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());
|
||||
|
||||
@@ -254,15 +280,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 = [
|
||||
|
||||
81
CliClient/tests/services_PluginService.ts
Normal file
81
CliClient/tests/services_PluginService.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
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');
|
||||
}));
|
||||
|
||||
});
|
||||
@@ -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/InteropService.js');
|
||||
const InteropService = require('lib/services/interop/InteropService').default;
|
||||
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.js');
|
||||
const shim = require('lib/shim').default;
|
||||
const SearchEngine = require('lib/services/searchengine/SearchEngine');
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
|
||||
@@ -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.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
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');
|
||||
const shim = require('lib/shim').default;
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
|
||||
@@ -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');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
|
||||
@@ -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');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const { shim } = require('lib/shim');
|
||||
const shim = require('lib/shim').default;
|
||||
const ResourceService = require('lib/services/ResourceService.js');
|
||||
|
||||
|
||||
|
||||
@@ -1,163 +1,162 @@
|
||||
/* 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');
|
||||
const ResourceService = require('lib/services/ResourceService.js');
|
||||
// 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();
|
||||
// });
|
||||
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
});
|
||||
// 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' });
|
||||
|
||||
let engine = null;
|
||||
// await engine.syncTables();
|
||||
// rows = await engine.search('Broke', { fuzzy: false });
|
||||
// expect(rows.length).toBe(0);
|
||||
|
||||
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('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('title:"Broke"', { fuzzy: true });
|
||||
// expect(rows.length).toBe(1);
|
||||
// expect(rows[0].id).toBe(n1.id);
|
||||
|
||||
rows = await engine.search('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('title: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);
|
||||
|
||||
rows = await engine.search('Imprtant', { fuzzy: true });
|
||||
expect(rows.length).toBe(1);
|
||||
expect(rows[0].id).toBe(n2.id);
|
||||
}));
|
||||
// await engine.syncTables();
|
||||
// rows = await engine.search('demand', { fuzzy: false });
|
||||
// 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('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();
|
||||
rows = await engine.search('demand', { fuzzy: false });
|
||||
expect(rows.length).toBe(1);
|
||||
expect(rows[0].id).toBe(n1.id);
|
||||
// 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' });
|
||||
|
||||
// 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('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);
|
||||
}));
|
||||
// const n7 = await Note.save({ title: 'he defenestrated the cat' });
|
||||
|
||||
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();
|
||||
|
||||
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('defenestrated cat', { fuzzy: true });
|
||||
// expect(rows.length).toBe(1);
|
||||
|
||||
const n7 = await Note.save({ title: 'he defenestrated the cat' });
|
||||
// rows = await engine.search('any:1 defenestrated cat', { fuzzy: true });
|
||||
// expect(rows.length).toBe(7);
|
||||
// }));
|
||||
|
||||
await engine.syncTables();
|
||||
// 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('defenestrated cat', { fuzzy: true });
|
||||
expect(rows.length).toBe(1);
|
||||
// await engine.syncTables();
|
||||
|
||||
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(2);
|
||||
// expect(rows.map(r=>r.id)).toContain(n1.id);
|
||||
// expect(rows.map(r=>r.id)).toContain(n4.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('"abc def"', { fuzzy: true });
|
||||
// expect(rows.length).toBe(1);
|
||||
// expect(rows.map(r=>r.id)).toContain(n1.id);
|
||||
|
||||
await engine.syncTables();
|
||||
// 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);
|
||||
|
||||
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('"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(1);
|
||||
expect(rows.map(r=>r.id)).toContain(n1.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('"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);
|
||||
// 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" mno', { fuzzy: true });
|
||||
expect(rows.length).toBe(1);
|
||||
expect(rows.map(r=>r.id)).toContain(n5.id);
|
||||
// await engine.syncTables();
|
||||
|
||||
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*', { fuzzy: true });
|
||||
|
||||
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' });
|
||||
// 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);
|
||||
// }));
|
||||
|
||||
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);
|
||||
}));
|
||||
|
||||
});
|
||||
// });
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
// /* 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);
|
||||
// }));
|
||||
|
||||
// });
|
||||
@@ -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');
|
||||
const Setting = require('lib/models/Setting');
|
||||
const shim = require('lib/shim').default;
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
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.setObjectKey('encryption.passwordCache', 'testing', '123456');
|
||||
Setting.setObjectValue('encryption.passwordCache', 'testing', '123456');
|
||||
await Setting.saveAll();
|
||||
await Setting.load();
|
||||
const passwords = Setting.value('encryption.passwordCache');
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user