Compare commits
1 Commits
server_fil
...
mobile_plu
Author | SHA1 | Date | |
---|---|---|---|
|
24263d12e2 |
@@ -1,9 +0,0 @@
|
||||
**/node_modules
|
||||
Assets/
|
||||
.git/
|
||||
_releases/
|
||||
packages/app-desktop
|
||||
packages/app-cli
|
||||
packages/app-mobile
|
||||
packages/app-clipper
|
||||
packages/generator-joplin
|
@@ -1,9 +0,0 @@
|
||||
# Example of local config, for development:
|
||||
#
|
||||
# JOPLIN_BASE_URL=http://localhost:22300
|
||||
# JOPLIN_PORT=22300
|
||||
|
||||
# Example of config for production:
|
||||
#
|
||||
# JOPLIN_BASE_URL=https://example.com/joplin
|
||||
# JOPLIN_PORT=22300
|
1943
.eslintignore
36
.eslintrc.js
@@ -1,5 +1,4 @@
|
||||
module.exports = {
|
||||
'root': true,
|
||||
'env': {
|
||||
'browser': true,
|
||||
'es6': true,
|
||||
@@ -16,8 +15,7 @@ module.exports = {
|
||||
'Atomics': 'readonly',
|
||||
'SharedArrayBuffer': 'readonly',
|
||||
|
||||
// Jest variables
|
||||
'test': 'readonly',
|
||||
// Jasmine variables
|
||||
'expect': 'readonly',
|
||||
'describe': 'readonly',
|
||||
'it': 'readonly',
|
||||
@@ -25,7 +23,7 @@ module.exports = {
|
||||
'afterAll': 'readonly',
|
||||
'beforeEach': 'readonly',
|
||||
'afterEach': 'readonly',
|
||||
'jest': 'readonly',
|
||||
'jasmine': 'readonly',
|
||||
|
||||
// React Native variables
|
||||
'__DEV__': 'readonly',
|
||||
@@ -35,9 +33,6 @@ module.exports = {
|
||||
'chrome': 'readonly',
|
||||
'browser': 'readonly',
|
||||
|
||||
// Server admin UI global variables
|
||||
'onDocumentReady': 'readonly',
|
||||
|
||||
'tinymce': 'readonly',
|
||||
},
|
||||
'parserOptions': {
|
||||
@@ -131,37 +126,10 @@ module.exports = {
|
||||
{
|
||||
// enable the rule specifically for TypeScript files
|
||||
'files': ['*.ts', '*.tsx'],
|
||||
'parserOptions': {
|
||||
// Required for @typescript-eslint/no-floating-promises
|
||||
'project': './tsconfig.eslint.json',
|
||||
},
|
||||
'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'],
|
||||
'@typescript-eslint/type-annotation-spacing': ['error', { 'before': false, 'after': true }],
|
||||
'@typescript-eslint/comma-dangle': ['error', {
|
||||
'arrays': 'always-multiline',
|
||||
'objects': 'always-multiline',
|
||||
'imports': 'always-multiline',
|
||||
'exports': 'always-multiline',
|
||||
'enums': 'always-multiline',
|
||||
'generics': 'always-multiline',
|
||||
'tuples': 'always-multiline',
|
||||
'functions': 'never',
|
||||
}],
|
||||
'@typescript-eslint/semi': ['error', 'always'],
|
||||
'@typescript-eslint/member-delimiter-style': ['error', {
|
||||
'multiline': {
|
||||
'delimiter': 'semi',
|
||||
'requireLast': true,
|
||||
},
|
||||
'singleline': {
|
||||
'delimiter': 'semi',
|
||||
'requireLast': false,
|
||||
},
|
||||
}],
|
||||
'@typescript-eslint/no-floating-promises': ['error'],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
15
.github/ISSUE_TEMPLATE/---feature-requests-and-support.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
name: "\U0001F914 Feature requests and support"
|
||||
about: 'For non-bug issues we recommend using the forum, where you''ll be more likely
|
||||
to get an answer: https://discourse.joplinapp.org/'
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
If this is a feature request or a support query, please note that you'll not get an answer here.
|
||||
|
||||
Instead we recommend using the forum where you'll are a lot more likely to get an answer: https://discourse.joplinapp.org/
|
||||
|
||||
The forum is also the right place to submit a feature request so that it can be discussed by other users.
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: "\U0001F914 Feature requests and support"
|
||||
url: https://discourse.joplinapp.org/
|
||||
about: I have a question or feature request …
|
1914
.gitignore
vendored
301
.ignore
Normal file
@@ -0,0 +1,301 @@
|
||||
# This is used by VSCode to ignore patterns during search.
|
||||
# Before they were in joplin.code-workspace, under the `files.exclude` key
|
||||
# but it eventually reached the limit with ENAMETOOLONG error.
|
||||
#
|
||||
# https://github.com/microsoft/vscode/issues/94718
|
||||
|
||||
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
|
||||
CliClient/app/LinkSelector.js
|
||||
CliClient/app/services/plugins/PluginRunner.js
|
||||
CliClient/tests/fsDriver.js
|
||||
CliClient/tests/InMemoryCache.js
|
||||
CliClient/tests/MdToHtml.js
|
||||
CliClient/tests/models_Setting.js
|
||||
CliClient/tests/services_CommandService.js
|
||||
CliClient/tests/services_InteropService.js
|
||||
CliClient/tests/services_keychainService.js
|
||||
CliClient/tests/services_PluginService.js
|
||||
CliClient/tests/services_rest_Api.js
|
||||
CliClient/tests/services/plugins/api/JoplinSetting.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/openProfileDirectory.js
|
||||
ElectronClient/commands/startExternalEditing.js
|
||||
ElectronClient/commands/stopExternalEditing.js
|
||||
ElectronClient/commands/toggleExternalEditing.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/KeymapConfig/KeymapConfigScreen.js
|
||||
ElectronClient/gui/KeymapConfig/ShortcutRecorder.js
|
||||
ElectronClient/gui/KeymapConfig/styles/index.js
|
||||
ElectronClient/gui/KeymapConfig/utils/getLabel.js
|
||||
ElectronClient/gui/KeymapConfig/utils/useCommandStatus.js
|
||||
ElectronClient/gui/KeymapConfig/utils/useKeymap.js
|
||||
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/newSubFolder.js
|
||||
ElectronClient/gui/MainScreen/commands/newTodo.js
|
||||
ElectronClient/gui/MainScreen/commands/openFolder.js
|
||||
ElectronClient/gui/MainScreen/commands/openNote.js
|
||||
ElectronClient/gui/MainScreen/commands/openTag.js
|
||||
ElectronClient/gui/MainScreen/commands/print.js
|
||||
ElectronClient/gui/MainScreen/commands/renameFolder.js
|
||||
ElectronClient/gui/MainScreen/commands/renameTag.js
|
||||
ElectronClient/gui/MainScreen/commands/search.js
|
||||
ElectronClient/gui/MainScreen/commands/selectTemplate.js
|
||||
ElectronClient/gui/MainScreen/commands/setTags.js
|
||||
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
|
||||
ElectronClient/gui/NoteEditor/commands/focusElementNoteBody.js
|
||||
ElectronClient/gui/NoteEditor/commands/focusElementNoteTitle.js
|
||||
ElectronClient/gui/NoteEditor/commands/showLocalSearch.js
|
||||
ElectronClient/gui/NoteEditor/commands/showRevisions.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/Editor.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/styles/index.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/Toolbar.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/index.js
|
||||
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
|
||||
ElectronClient/gui/NoteEditor/styles/index.js
|
||||
ElectronClient/gui/NoteEditor/utils/contextMenu.js
|
||||
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/TagList.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/plugins/GotoAnything.js
|
||||
ElectronClient/services/bridge.js
|
||||
ElectronClient/services/commands/types.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/BackButtonDialogBox.js
|
||||
ReactNativeClient/lib/components/CameraView.js
|
||||
ReactNativeClient/lib/components/NoteBodyViewer/hooks/useOnMessage.js
|
||||
ReactNativeClient/lib/components/NoteBodyViewer/hooks/useOnResourceLongPress.js
|
||||
ReactNativeClient/lib/components/NoteBodyViewer/hooks/useSource.js
|
||||
ReactNativeClient/lib/components/NoteBodyViewer/NoteBodyViewer.js
|
||||
ReactNativeClient/lib/components/screens/Note.js
|
||||
ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js
|
||||
ReactNativeClient/lib/components/SelectDateTimeDialog.js
|
||||
ReactNativeClient/lib/errorUtils.js
|
||||
ReactNativeClient/lib/eventManager.js
|
||||
ReactNativeClient/lib/fs-driver-node.js
|
||||
ReactNativeClient/lib/hooks/useEffectDebugger.js
|
||||
ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js
|
||||
ReactNativeClient/lib/hooks/usePrevious.js
|
||||
ReactNativeClient/lib/hooks/usePropsDebugger.js
|
||||
ReactNativeClient/lib/InMemoryCache.js
|
||||
ReactNativeClient/lib/joplin-renderer/MarkupToHtml.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/code_inline.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fountain.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/highlight_keywords.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/html_image.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/image.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/katex.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/link_open.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.js
|
||||
ReactNativeClient/lib/joplin-renderer/noteStyle.js
|
||||
ReactNativeClient/lib/joplin-renderer/pathUtils.js
|
||||
ReactNativeClient/lib/JoplinServerApi.js
|
||||
ReactNativeClient/lib/locale.js
|
||||
ReactNativeClient/lib/Logger.js
|
||||
ReactNativeClient/lib/markdownUtils.js
|
||||
ReactNativeClient/lib/markupLanguageUtils.js
|
||||
ReactNativeClient/lib/models/Alarm.js
|
||||
ReactNativeClient/lib/models/Setting.js
|
||||
ReactNativeClient/lib/ntpDate.js
|
||||
ReactNativeClient/lib/path-utils.js
|
||||
ReactNativeClient/lib/PoorManIntervals.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/commands/commandsToMarkdownTable.js
|
||||
ReactNativeClient/lib/services/commands/MenuUtils.js
|
||||
ReactNativeClient/lib/services/commands/propsHaveChanged.js
|
||||
ReactNativeClient/lib/services/commands/stateToWhenClauseContext.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/JoplinViewsMenus.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/MenuController.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/contentScriptsToRendererRules.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
|
||||
ReactNativeClient/lib/services/SettingUtils.js
|
||||
ReactNativeClient/lib/services/synchronizer/gui/useSyncTargetUpgrade.js
|
||||
ReactNativeClient/lib/services/synchronizer/LockHandler.js
|
||||
ReactNativeClient/lib/services/synchronizer/MigrationHandler.js
|
||||
ReactNativeClient/lib/services/synchronizer/migrations/1.js
|
||||
ReactNativeClient/lib/services/synchronizer/migrations/2.js
|
||||
ReactNativeClient/lib/services/synchronizer/utils/types.js
|
||||
ReactNativeClient/lib/services/UndoRedoService.js
|
||||
ReactNativeClient/lib/services/WhenClause.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
|
||||
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
|
62
.travis.yml
@@ -1,5 +1,5 @@
|
||||
# Only build tags (Doesn't work - doesn't build anything)
|
||||
if: tag IS present OR type = pull_request OR branch = dev
|
||||
if: tag IS present OR type = pull_request
|
||||
|
||||
rvm: 2.3.3
|
||||
|
||||
@@ -15,30 +15,21 @@ branches:
|
||||
matrix:
|
||||
include:
|
||||
- os: osx
|
||||
osx_image: xcode12
|
||||
osx_image: xcode9.0
|
||||
language: node_js
|
||||
node_js: "12"
|
||||
cache:
|
||||
npm: false
|
||||
# Cache was disabled because when changing from node_js 10 to node_js 12
|
||||
# it was still using build files from Node 10 when building SQLite which
|
||||
# was making it fail. Might be ok to re-enable later on, although it doesn't
|
||||
# make build that much faster.
|
||||
#
|
||||
# env:
|
||||
# - ELECTRON_CACHE=$HOME/.cache/electron
|
||||
# - ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder
|
||||
node_js: "10"
|
||||
env:
|
||||
- ELECTRON_CACHE=$HOME/.cache/electron
|
||||
- ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder
|
||||
|
||||
- os: linux
|
||||
sudo: required
|
||||
dist: trusty
|
||||
language: node_js
|
||||
node_js: "12"
|
||||
cache:
|
||||
npm: false
|
||||
# env:
|
||||
# - ELECTRON_CACHE=$HOME/.cache/electron
|
||||
# - ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder
|
||||
node_js: "10"
|
||||
env:
|
||||
- ELECTRON_CACHE=$HOME/.cache/electron
|
||||
- ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder
|
||||
|
||||
# cache:
|
||||
# directories:
|
||||
@@ -68,24 +59,23 @@ before_install:
|
||||
|
||||
script:
|
||||
- |
|
||||
# Prints some env variables
|
||||
echo "TRAVIS_OS_NAME=$TRAVIS_OS_NAME"
|
||||
echo "TRAVIS_BRANCH=$TRAVIS_BRANCH"
|
||||
echo "TRAVIS_PULL_REQUEST=$TRAVIS_PULL_REQUEST"
|
||||
echo "TRAVIS_TAG=$TRAVIS_TAG"
|
||||
|
||||
# Install tools
|
||||
npm install
|
||||
cd Tools
|
||||
npm install
|
||||
cd ..
|
||||
|
||||
# Run test units.
|
||||
# Only do it for pull requests because Travis randomly fails to run them
|
||||
# and that would break the desktop release.
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ] || [ "$TRAVIS_BRANCH" = "dev" ]; then
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
|
||||
cd CliClient
|
||||
npm run test-ci
|
||||
testResult=$?
|
||||
if [ $testResult -ne 0 ]; then
|
||||
exit $testResult
|
||||
fi
|
||||
cd ..
|
||||
fi
|
||||
|
||||
# Run linter for pull requests only - this is so that
|
||||
@@ -103,7 +93,7 @@ script:
|
||||
# tool like poedit. Doing it for Linux only is sufficient.
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
|
||||
if [ "$TRAVIS_OS_NAME" != "osx" ]; then
|
||||
node packages/tools/validate-translation.js
|
||||
node Tools/validate-translation.js
|
||||
testResult=$?
|
||||
if [ $testResult -ne 0 ]; then
|
||||
exit $testResult
|
||||
@@ -112,7 +102,7 @@ script:
|
||||
fi
|
||||
|
||||
# Find out if we should run the build or not. Electron-builder gets stuck when
|
||||
# building PRs so we disable it in this case. The Linux build should provide
|
||||
# builing PRs so we disable it in this case. The Linux build should provide
|
||||
# enough info if the app builds or not.
|
||||
# https://github.com/electron-userland/electron-builder/issues/4263
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
|
||||
@@ -122,17 +112,5 @@ script:
|
||||
fi
|
||||
|
||||
# Prepare the Electron app and build it
|
||||
#
|
||||
# If the current tag is a desktop release tag (starts with "v", such as
|
||||
# "v1.4.7"), we build and publish to github
|
||||
#
|
||||
# Otherwise we only build but don't publish to GitHub. It helps finding
|
||||
# out any issue in pull requests and dev branch.
|
||||
|
||||
cd packages/app-desktop
|
||||
|
||||
if [[ $TRAVIS_TAG = v* ]]; then
|
||||
USE_HARD_LINKS=false npm run dist
|
||||
else
|
||||
USE_HARD_LINKS=false npm run dist -- --publish=never
|
||||
fi
|
||||
cd ElectronClient
|
||||
USE_HARD_LINKS=false npm run dist
|
||||
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 300 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 71 KiB |
58
BUILD.md
@@ -2,24 +2,11 @@
|
||||
|
||||
# Building the applications
|
||||
|
||||
The Joplin source code is hosted on a [monorepo](https://en.wikipedia.org/wiki/Monorepo) managed by Lerna. The usage of Lerna is mostly transparent as the needed commands have been moved to the root package.json and thus are invoked for example when running `npm install` or `npm run watch`. The main thing to know about Lerna is that it links the packages in the monorepo using `npm link`, so if you check the node_modules directory you will see links instead of actual directories for certain packages. This is something to keep in mind as these links can cause issues in some cases.
|
||||
|
||||
The list of the main sub-packages is below:
|
||||
|
||||
Package name | Description
|
||||
--- | ---
|
||||
app-cli | The CLI application
|
||||
app-clipper | The web clipper
|
||||
app-desktop | The desktop application
|
||||
app-mobile | The mobile application
|
||||
lib | The core library, shared by all applications. It deals with things like synchronisation, encryption, import/export, database and pretty much all the app business logic
|
||||
renderer | The Joplin Markdown and HTML renderer
|
||||
tools | Tools used to build the apps and other tasks
|
||||
|
||||
There are also a few forks of existing packages under the "fork-*" name.
|
||||
Note that all the applications share the same library, which, for historical reasons, is in `ReactNativeClient/lib`. This library is copied to the relevant directories when building each app.
|
||||
|
||||
## Required dependencies
|
||||
|
||||
- Install yarn - https://yarnpkg.com/lang/en/docs/install/
|
||||
- Install node 10+ - https://nodejs.org/en/
|
||||
- macOS, Linux: Install rsync - https://nodejs.org/en/
|
||||
- macOS: Install Cocoapods - `brew install cocoapods`
|
||||
@@ -36,32 +23,33 @@ Then you can test the various applications:
|
||||
|
||||
## Testing the desktop application
|
||||
|
||||
cd packages/app-desktop
|
||||
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 packages/app-cli
|
||||
cd CliClient
|
||||
npm start
|
||||
|
||||
## Testing the Mobile application
|
||||
|
||||
First you need to setup React Native to build projects with native code. For this, follow the instructions on the [Get Started](https://facebook.github.io/react-native/docs/getting-started.html) tutorial, in the "React Native CLI Quickstart" tab.
|
||||
|
||||
Then, for **Android**:
|
||||
Then:
|
||||
|
||||
cd packages/app-mobile/android
|
||||
./gradlew installDebug # or gradlew.bat installDebug on Windows
|
||||
cd ReactNativeClient
|
||||
npm run start-android
|
||||
# Or: npm run start-ios
|
||||
|
||||
On **iOS**, open the file `ios/Joplin.xcworkspace` on XCode and run the app from there.
|
||||
To run the iOS application, it might be easier to open the file `ios/Joplin.xcworkspace` on XCode and run the app from there.
|
||||
|
||||
Normally the **bundler** should start automatically with the application. If it doesn't, run `npm start` from `packages/app-mobile`.
|
||||
Normally the bundler should start automatically with the application. If it doesn't, run `npm start`.
|
||||
|
||||
## Building the clipper
|
||||
|
||||
cd packages/app-clipper/popup
|
||||
cd Clipper/popup
|
||||
npm install
|
||||
npm run watch # To watch for changes
|
||||
|
||||
@@ -69,36 +57,30 @@ To test the extension please refer to the relevant pages for each browser: [Fire
|
||||
|
||||
## Watching files
|
||||
|
||||
To make changes to the application, you'll need to rebuild any TypeScript file you've changed. The simplest way to do this is to watch for changes from the root of the project. Simply run this command, and it should take care of the rest:
|
||||
To make changes to the application, you'll need to rebuild any TypeScript file you've changed, and rebuild the lib. The simplest way to do all this is to watch for changes from the root of the project. Simply run this command, and it should take care of the rest:
|
||||
|
||||
npm run watch
|
||||
|
||||
Running `npm run tsc` would have the same effect, but without watching.
|
||||
Running `npm run build` would have the same effect, but without watching.
|
||||
|
||||
## Running an application with additional parameters
|
||||
|
||||
You can specify additional parameters when running the desktop or CLI application. To do so, add `--` to the `npm start` command, followed by your flags. For example:
|
||||
|
||||
npm start -- --debug
|
||||
|
||||
## Adding a new dependency
|
||||
|
||||
Since Joplin uses Lerna, adding a new dependency should not be done using `npm i -s ...`. Instead you should use the `lerna add` command, which will take care of adding the package while handling the linked packages correctly. For example, to add the package "leftpad" to the "app-desktop" sub-package, you would run:
|
||||
|
||||
npx lerna add leftpad --scope=@joplin/app-desktop
|
||||
|
||||
Note that you should most likely always specify a scope because otherwise it will add the package to all the sub-packages.
|
||||
npm start -- --profile ~/MyTestProfile
|
||||
|
||||
## TypeScript
|
||||
|
||||
The application was originally written in JavaScript, however it has slowly been migrated to [TypeScript](https://www.typescriptlang.org/). New classes and files should be written in TypeScript. All compiled files are generated next to the .ts or .tsx file. So for example, if there's a file "lib/MyClass.ts", there will be a generated "lib/MyClass.js" next to it. It is implemented that way as it requires minimal changes to integrate TypeScript in the existing JavaScript code base.
|
||||
Most of the application is written in JavaScript, however new classes and files should generally be written in [TypeScript](https://www.typescriptlang.org/). All TypeScript files are generated next to the .ts or .tsx file. So for example, if there's a file "lib/MyClass.ts", there will be a generated "lib/MyClass.js" next to it. It is implemented that way as it requires minimal changes to integrate TypeScript in the existing JavaScript code base.
|
||||
|
||||
In the current setup, `tsc` is executed from the root of the project, and will compile everything in CliClient, ElectronClient, etc. This is more convenient to have just one place to compile everything, and it also means there's only one watch command to run. However, one drawback is that TypeScript doesn't find types defined in node_modules folders in sub-directories. For example, if you install `immer` in ElectronClient, then try to use the package, TypeScript will report that it cannot find this module. In theory using `typeRoots`, it should be possible to make it find the right modules but it doesn't seem to work in this case. Currently the workaround is to install any such package at the root of the project. By doing so, TypeScript will find the type definitions and compilation will work. It's not ideal since the module is installed at the root even though it's not used, but for now that will work.
|
||||
|
||||
## Hot reload
|
||||
|
||||
If you'd like to auto-reload the desktop app on changes rather than having to quit and restart it manually each time, you can use [watchman-make](https://facebook.github.io/watchman/docs/watchman-make.html):
|
||||
|
||||
```sh
|
||||
cd packages/app-desktop
|
||||
cd ElectronClient
|
||||
watchman-make -p '**/*.js' '**/*.jsx' --run "npm start"
|
||||
```
|
||||
|
||||
@@ -108,6 +90,10 @@ It still requires you to quit the application each time you want it to rebuild,
|
||||
2. Switch to the Electron app and <kbd>cmd</kbd>+<kbd>Q</kbd> to quit it.
|
||||
3. `watchman` immediately restarts the app for you (whereas usually you'd have to switch back to the terminal, type `"npm start"`, and hit enter).
|
||||
|
||||
# Updating Markdown renderer packages
|
||||
|
||||
The Markdown renderer is located under ReactNativeClient/lib/joplin-renderer. Whenever updating one of its dependencies, such as Mermaid or Katex, please run `npm run buildAssets` to make sure all assets such as fonts or CSS files are deployed correctly.
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
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.
|
@@ -44,9 +44,9 @@ Building the apps is relatively easy - please [see the build instructions](https
|
||||
|
||||
Coding style is enforced by a pre-commit hook that runs eslint. This hook is installed whenever running `npm install` on any of the application directory. If for some reason the pre-commit hook didn't get installed, you can manually install it by running `npm install` at the root of the repository.
|
||||
|
||||
For new React components, please use [React Hooks](https://reactjs.org/docs/hooks-intro.html). For new code in general, please use TypeScript. Even if you are modifying a file that was originally in JavaScript you should ideally convert it first to TypeScript before modifying it. Doing so is relatively easy and it helps maintain code quality.
|
||||
For new React components, please use [React Hooks](https://reactjs.org/docs/hooks-intro.html). For new code in general, please use TypeScript (unless you are modifying a file that was originally in JavaScript).
|
||||
|
||||
For changes made to the Desktop client that affect the user interface, refer to `packages/app-desktop/theme.ts` for all styling information. The goal is to create a consistent user interface to allow for easy navigation of Joplin's various features and improve the overall user experience.
|
||||
For changes made to the Desktop client that affect the user interface, refer to `ElectronClient/app/theme.js` for all styling information. The goal is to create a consistent user interface to allow for easy navigation of Joplin's various features and improve the overall user experience.
|
||||
|
||||
## Automated tests
|
||||
|
||||
@@ -56,11 +56,11 @@ When submitting a pull request for a new feature or a bug fix, please add automa
|
||||
|
||||
* **Feature tests** on the other hand are to test higher level functionalities such as interactions with the GUI and how they affect the underlying model. Often these tests would dispatch Redux actions, and inspect how the application state has been changed. The feature tests should be prefixed with "feature_", for example "feature_TagList". There's a good explanation on what qualifies as a feature test in [this post](https://github.com/laurent22/joplin/pull/2819#issuecomment-603502230).
|
||||
|
||||
The tests are under packages/app-cli/tests. To get them running, you first need to build the CLI app:
|
||||
The tests are under CliClient/tests. To get them running, you first need to build the CLI app:
|
||||
|
||||
```sh
|
||||
npm install
|
||||
cd packages/app-cli
|
||||
cd CliClient
|
||||
```
|
||||
|
||||
To run all the test units:
|
||||
|
@@ -41,8 +41,7 @@ class LinkSelector {
|
||||
const newLinkStore: LinkStoreEntry[] = [];
|
||||
const lines: string[] = renderedText.split('\n');
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const r = (lines[i] as any).matchAll(this.linkRegex_);
|
||||
const matches = [...r];
|
||||
const matches = [...lines[i].matchAll(this.linkRegex_)];
|
||||
matches.forEach((_e, n) => {
|
||||
newLinkStore.push(
|
||||
{
|
@@ -1,5 +1,5 @@
|
||||
const Logger = require('@joplin/lib/Logger').default;
|
||||
const { netUtils } = require('@joplin/lib/net-utils.js');
|
||||
const Logger = require('lib/Logger').default;
|
||||
const { netUtils } = require('lib/net-utils.js');
|
||||
|
||||
const http = require('http');
|
||||
const urlParser = require('url');
|
@@ -1,17 +1,17 @@
|
||||
const Logger = require('@joplin/lib/Logger').default;
|
||||
const Folder = require('@joplin/lib/models/Folder.js');
|
||||
const BaseItem = require('@joplin/lib/models/BaseItem.js');
|
||||
const Tag = require('@joplin/lib/models/Tag.js');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const Resource = require('@joplin/lib/models/Resource.js');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const reducer = require('@joplin/lib/reducer').default;
|
||||
const { defaultState } = require('@joplin/lib/reducer');
|
||||
const { splitCommandString } = require('@joplin/lib/string-utils.js');
|
||||
const { reg } = require('@joplin/lib/registry.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
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').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');
|
||||
const shim = require('lib/shim').default;
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlentities = new Entities().encode;
|
||||
|
||||
@@ -19,7 +19,7 @@ const chalk = require('chalk');
|
||||
const tk = require('terminal-kit');
|
||||
const TermWrapper = require('tkwidgets/framework/TermWrapper.js');
|
||||
const Renderer = require('tkwidgets/framework/Renderer.js');
|
||||
const DecryptionWorker = require('@joplin/lib/services/DecryptionWorker');
|
||||
const DecryptionWorker = require('lib/services/DecryptionWorker');
|
||||
|
||||
const BaseWidget = require('tkwidgets/BaseWidget.js');
|
||||
const TextWidget = require('tkwidgets/TextWidget.js');
|
@@ -1,20 +1,20 @@
|
||||
const BaseApplication = require('@joplin/lib/BaseApplication').default;
|
||||
const { FoldersScreenUtils } = require('@joplin/lib/folders-screen-utils.js');
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const Folder = require('@joplin/lib/models/Folder.js');
|
||||
const BaseItem = require('@joplin/lib/models/BaseItem.js');
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const Tag = require('@joplin/lib/models/Tag.js');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const { reg } = require('@joplin/lib/registry.js');
|
||||
const { fileExtension } = require('@joplin/lib/path-utils');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
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');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const BaseItem = require('lib/models/BaseItem.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const { reg } = require('lib/registry.js');
|
||||
const { fileExtension } = require('lib/path-utils');
|
||||
const { _ } = require('lib/locale');
|
||||
const fs = require('fs-extra');
|
||||
const { cliUtils } = require('./cli-utils.js');
|
||||
const Cache = require('@joplin/lib/Cache');
|
||||
const RevisionService = require('@joplin/lib/services/RevisionService');
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
const Cache = require('lib/Cache');
|
||||
const RevisionService = require('lib/services/RevisionService');
|
||||
const shim = require('lib/shim').default;
|
||||
|
||||
class Application extends BaseApplication {
|
||||
constructor() {
|
||||
@@ -426,7 +426,7 @@ class Application extends BaseApplication {
|
||||
|
||||
const AppGui = require('./app-gui.js');
|
||||
this.gui_ = new AppGui(this, this.store(), keymap);
|
||||
this.gui_.setLogger(this.logger());
|
||||
this.gui_.setLogger(this.logger_);
|
||||
await this.gui_.start();
|
||||
|
||||
// Since the settings need to be loaded before the store is created, it will never
|
@@ -1,7 +1,7 @@
|
||||
const { app } = require('./app.js');
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const Folder = require('@joplin/lib/models/Folder.js');
|
||||
const Tag = require('@joplin/lib/models/Tag.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
const { cliUtils } = require('./cli-utils.js');
|
||||
const yargParser = require('yargs-parser');
|
||||
const fs = require('fs-extra');
|
@@ -1,5 +1,5 @@
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { reg } = require('@joplin/lib/registry.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const { reg } = require('lib/registry.js');
|
||||
|
||||
class BaseCommand {
|
||||
constructor() {
|
@@ -1,7 +1,7 @@
|
||||
const fs = require('fs-extra');
|
||||
const { fileExtension, dirname } = require('@joplin/lib/path-utils');
|
||||
const { fileExtension, dirname } = require('lib/path-utils');
|
||||
const wrap_ = require('word-wrap');
|
||||
const { languageCode } = require('@joplin/lib/locale');
|
||||
const { languageCode } = require('lib/locale');
|
||||
|
||||
const rootDir = dirname(dirname(__dirname));
|
||||
const MAX_WIDTH = 78;
|
@@ -1,17 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs-extra');
|
||||
const Logger = require('@joplin/lib/Logger').default;
|
||||
const { dirname } = require('@joplin/lib/path-utils');
|
||||
const { DatabaseDriverNode } = require('@joplin/lib/database-driver-node.js');
|
||||
const { JoplinDatabase } = require('@joplin/lib/joplin-database.js');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const Folder = require('@joplin/lib/models/Folder.js');
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const Logger = require('lib/Logger').default;
|
||||
const { dirname } = require('lib/path-utils');
|
||||
const { DatabaseDriverNode } = require('lib/database-driver-node.js');
|
||||
const { JoplinDatabase } = require('lib/joplin-database.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const { sprintf } = require('sprintf-js');
|
||||
const exec = require('child_process').exec;
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.error('Unhandled promise rejection', p, 'reason:', reason);
|
||||
});
|
||||
|
||||
const baseDir = `${dirname(__dirname)}/tests/cli-integration`;
|
||||
const joplinAppPath = `${__dirname}/main.js`;
|
||||
|
@@ -1,8 +1,8 @@
|
||||
const yargParser = require('yargs-parser');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { _ } = require('lib/locale');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
const stringPadding = require('string-padding');
|
||||
const Logger = require('@joplin/lib/Logger').default;
|
||||
const Logger = require('lib/Logger').default;
|
||||
|
||||
const cliUtils = {};
|
||||
|
@@ -1,15 +1,14 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const BaseItem = require('@joplin/lib/models/BaseItem');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const { toTitleCase } = require('@joplin/lib/string-utils.js');
|
||||
const { reg } = require('@joplin/lib/registry.js');
|
||||
const markdownUtils = require('@joplin/lib/markdownUtils').default;
|
||||
const { Database } = require('@joplin/lib/database.js');
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
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').default;
|
||||
const { Database } = require('lib/database.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
||||
return 'apidoc <file>';
|
||||
return 'apidoc';
|
||||
}
|
||||
|
||||
description() {
|
||||
@@ -36,7 +35,7 @@ class Command extends BaseCommand {
|
||||
return markdownUtils.createMarkdownTable(headers, tableFields);
|
||||
}
|
||||
|
||||
async action(args) {
|
||||
async action() {
|
||||
const models = [
|
||||
{
|
||||
type: BaseModel.TYPE_NOTE,
|
||||
@@ -113,50 +112,6 @@ class Command extends BaseCommand {
|
||||
lines.push('');
|
||||
lines.push('\tcurl http://localhost:41184/tags?fields=id');
|
||||
lines.push('');
|
||||
lines.push('By default API results will contain the following fields: **id**, **parent_id**, **title**');
|
||||
|
||||
lines.push('# Pagination');
|
||||
lines.push('');
|
||||
lines.push('All API calls that return multiple results will be paginated and will return the following structure:');
|
||||
lines.push('');
|
||||
lines.push('Key | Always present? | Description');
|
||||
lines.push('--- | --- | ---');
|
||||
lines.push('`items` | Yes | The array of items you have requested.');
|
||||
lines.push('`has_more` | Yes | If `true`, there are more items after this page. If `false`, it means you have reached the end of the data set.');
|
||||
lines.push('');
|
||||
lines.push('You can specify how the results should be sorted using the `order_by` and `order_dir` query parameters, and which page to retrieve using the `page` parameter (starts at and defaults to 1). You can specify the number of items to be returned using the `limit` parameter (the maximum being 100 items).');
|
||||
lines.push('');
|
||||
lines.push('The following call for example will initiate a request to fetch all the notes, 10 at a time, and sorted by "updated_time" ascending:');
|
||||
lines.push('');
|
||||
lines.push('\tcurl http://localhost:41184/notes?order_by=updated_time&order_dir=ASC&limit=10');
|
||||
lines.push('');
|
||||
lines.push('This will return a result like this');
|
||||
lines.push('');
|
||||
lines.push('\t{ "items": [ /* 10 notes */ ], "has_more": true }');
|
||||
lines.push('');
|
||||
lines.push('Then you will resume fetching the results using this query:');
|
||||
lines.push('');
|
||||
lines.push('\tcurl http://localhost:41184/notes?order_by=updated_time&order_dir=ASC&limit=10&page=2');
|
||||
lines.push('');
|
||||
lines.push('Eventually you will get some results that do not contain an "has_more" paramater, at which point you will have retrieved all the results');
|
||||
lines.push('');
|
||||
lines.push('As an example the pseudo-code below could be used to fetch all the notes:');
|
||||
lines.push('');
|
||||
lines.push('```javascript');
|
||||
lines.push(`
|
||||
async function fetchJson(url) {
|
||||
return (await fetch(url)).json();
|
||||
}
|
||||
|
||||
async function fetchAllNotes() {
|
||||
let pageNum = 1;
|
||||
do {
|
||||
const response = await fetchJson((http://localhost:41184/notes?page=' + pageNum++);
|
||||
console.info('Printing notes:', response.items);
|
||||
} while (response.has_more)
|
||||
}`);
|
||||
lines.push('```');
|
||||
lines.push('');
|
||||
|
||||
lines.push('# Error handling');
|
||||
lines.push('');
|
||||
@@ -293,11 +248,6 @@ async function fetchAllNotes() {
|
||||
lines.push('');
|
||||
lines.push('Gets the actual file associated with this resource.');
|
||||
lines.push('');
|
||||
|
||||
lines.push('## GET /resources/:id/notes');
|
||||
lines.push('');
|
||||
lines.push('Gets the notes (IDs) associated with a resource.');
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
lines.push(`## POST /${tableName}`);
|
||||
@@ -364,9 +314,7 @@ async function fetchAllNotes() {
|
||||
}
|
||||
}
|
||||
|
||||
const outFilePath = args['file'];
|
||||
|
||||
await shim.fsDriver().writeFile(outFilePath, lines.join('\n'), 'utf8');
|
||||
this.stdout(lines.join('\n'));
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const shim = require('lib/shim').default;
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,9 +1,9 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const BaseItem = require('@joplin/lib/models/BaseItem.js');
|
||||
const Note = require('@joplin/lib/models/Note.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');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,8 +1,8 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { _, setLocale } = require('@joplin/lib/locale');
|
||||
const { _, setLocale } = require('lib/locale');
|
||||
const { app } = require('./app.js');
|
||||
const fs = require('fs-extra');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,8 +1,8 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,9 +1,9 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,7 +1,7 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const Folder = require('@joplin/lib/models/Folder.js');
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const Tag = require('@joplin/lib/models/Tag.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,11 +1,11 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const EncryptionService = require('@joplin/lib/services/EncryptionService');
|
||||
const DecryptionWorker = require('@joplin/lib/services/DecryptionWorker');
|
||||
const BaseItem = require('@joplin/lib/models/BaseItem');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
const pathUtils = require('@joplin/lib/path-utils');
|
||||
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').default;
|
||||
const shim = require('lib/shim').default;
|
||||
const pathUtils = require('lib/path-utils');
|
||||
const imageType = require('image-type');
|
||||
const readChunk = require('read-chunk');
|
||||
|
||||
@@ -45,12 +45,10 @@ class Command extends BaseCommand {
|
||||
|
||||
const startDecryption = async () => {
|
||||
this.stdout(_('Starting decryption... Please wait as it may take several minutes depending on how much there is to decrypt.'));
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
const result = await DecryptionWorker.instance().start();
|
||||
|
||||
if (result.error) throw result.error;
|
||||
|
||||
const line = [];
|
||||
line.push(_('Decrypted items: %d', result.decryptedItemCount));
|
||||
if (result.skippedItemCount) line.push(_('Skipped items: %d (use --retry-failed-items to retry decrypting them)', result.skippedItemCount));
|
@@ -1,12 +1,12 @@
|
||||
const fs = require('fs-extra');
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { splitCommandString } = require('@joplin/lib/string-utils.js');
|
||||
const uuid = require('@joplin/lib/uuid').default;
|
||||
const { splitCommandString } = require('lib/string-utils.js');
|
||||
const uuid = require('lib/uuid').default;
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const { _ } = require('lib/locale');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { _ } = require('lib/locale');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,7 +1,7 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const { ReportService } = require('@joplin/lib/services/report.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const { ReportService } = require('lib/services/report.js');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
class Command extends BaseCommand {
|
@@ -1,8 +1,8 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const InteropService = require('@joplin/lib/services/interop/InteropService').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const InteropService = require('lib/services/interop/InteropService').default;
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { _ } = require('lib/locale');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,8 +1,8 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,7 +1,7 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { renderCommandHelp } = require('./help-utils.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
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('@joplin/lib/services/interop/InteropService').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
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('@joplin/lib/locale');
|
||||
const { _ } = require('lib/locale');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
||||
@@ -55,7 +55,7 @@ class Command extends BaseCommand {
|
||||
};
|
||||
|
||||
importOptions.onError = error => {
|
||||
const s = error.stack ? error.stack : error.toString();
|
||||
const s = error.trace ? error.trace : error.toString();
|
||||
this.stdout(s);
|
||||
};
|
||||
|
@@ -1,12 +1,12 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const Folder = require('@joplin/lib/models/Folder.js');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const Note = require('lib/models/Note.js');
|
||||
const { sprintf } = require('sprintf-js');
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { time } = require('lib/time-utils.js');
|
||||
const { cliUtils } = require('./cli-utils.js');
|
||||
|
||||
class Command extends BaseCommand {
|
@@ -1,7 +1,7 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const Folder = require('@joplin/lib/models/Folder.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,7 +1,7 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const Note = require('lib/models/Note.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,7 +1,7 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const Note = require('lib/models/Note.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,9 +1,9 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const Folder = require('@joplin/lib/models/Folder.js');
|
||||
const Note = require('@joplin/lib/models/Note.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');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,9 +1,9 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const Folder = require('@joplin/lib/models/Folder.js');
|
||||
const Note = require('@joplin/lib/models/Note.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');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,8 +1,8 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const Folder = require('@joplin/lib/models/Folder.js');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const { _ } = require('lib/locale');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,8 +1,8 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const { _ } = require('lib/locale');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,8 +1,8 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const Folder = require('@joplin/lib/models/Folder.js');
|
||||
const uuid = require('@joplin/lib/uuid').default;
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const uuid = require('lib/uuid').default;
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,8 +1,8 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const Logger = require('@joplin/lib/Logger').default;
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
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 {
|
||||
|
||||
@@ -17,7 +17,7 @@ class Command extends BaseCommand {
|
||||
async action(args) {
|
||||
const command = args.command;
|
||||
|
||||
const ClipperServer = require('@joplin/lib/ClipperServer');
|
||||
const ClipperServer = require('lib/ClipperServer');
|
||||
ClipperServer.instance().initialize();
|
||||
const stdoutFn = (...s) => this.stdout(s.join(' '));
|
||||
const clipperLogger = new Logger();
|
@@ -1,9 +1,9 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const { Database } = require('@joplin/lib/database.js');
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const { Database } = require('lib/database.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,8 +1,8 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { ReportService } = require('@joplin/lib/services/report.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const { _ } = require('lib/locale');
|
||||
const { ReportService } = require('lib/services/report.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,17 +1,17 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { OneDriveApiNodeUtils } = require('@joplin/lib/onedrive-api-node-utils.js');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const ResourceFetcher = require('@joplin/lib/services/ResourceFetcher');
|
||||
const Synchronizer = require('@joplin/lib/Synchronizer').default;
|
||||
const { reg } = require('@joplin/lib/registry.js');
|
||||
const { _ } = require('lib/locale');
|
||||
const { OneDriveApiNodeUtils } = require('lib/onedrive-api-node-utils.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const ResourceFetcher = require('lib/services/ResourceFetcher');
|
||||
const Synchronizer = require('lib/Synchronizer').default;
|
||||
const { reg } = require('lib/registry.js');
|
||||
const { cliUtils } = require('./cli-utils.js');
|
||||
const md5 = require('md5');
|
||||
const locker = require('proper-lockfile');
|
||||
const fs = require('fs-extra');
|
||||
const SyncTargetRegistry = require('@joplin/lib/SyncTargetRegistry');
|
||||
const MigrationHandler = require('@joplin/lib/services/synchronizer/MigrationHandler').default;
|
||||
const SyncTargetRegistry = require('lib/SyncTargetRegistry');
|
||||
const MigrationHandler = require('lib/services/synchronizer/MigrationHandler').default;
|
||||
|
||||
class Command extends BaseCommand {
|
||||
constructor() {
|
@@ -1,9 +1,9 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const Tag = require('@joplin/lib/models/Tag.js');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { _ } = require('lib/locale');
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,9 +1,9 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,5 +1,5 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { _ } = require('lib/locale');
|
||||
|
||||
const CommandDone = require('./command-done.js');
|
||||
|
@@ -1,7 +1,7 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const { _ } = require('lib/locale');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,6 +1,6 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const { _ } = require('lib/locale');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
@@ -1,10 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const Logger = require('@joplin/lib/Logger').default;
|
||||
const Resource = require('@joplin/lib/models/Resource.js');
|
||||
const { dirname } = require('@joplin/lib/path-utils');
|
||||
const FsDriverNode = require('@joplin/lib/fs-driver-node').default;
|
||||
const { time } = require('lib/time-utils.js');
|
||||
const Logger = require('lib/Logger').default;
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const { dirname } = require('lib/path-utils');
|
||||
const FsDriverNode = require('lib/fs-driver-node').default;
|
||||
const lodash = require('lodash');
|
||||
const exec = require('child_process').exec;
|
||||
const fs = require('fs-extra');
|
||||
@@ -22,6 +22,10 @@ const logger = new Logger();
|
||||
logger.addTarget('console');
|
||||
logger.setLevel(Logger.LEVEL_DEBUG);
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.error('Unhandled promise rejection', p, 'reason:', reason);
|
||||
});
|
||||
|
||||
function createClient(id) {
|
||||
return {
|
||||
id: id,
|
@@ -1,8 +1,8 @@
|
||||
const Folder = require('@joplin/lib/models/Folder.js');
|
||||
const Tag = require('@joplin/lib/models/Tag.js');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
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('@joplin/lib/locale')._;
|
||||
const _ = require('lib/locale')._;
|
||||
|
||||
class FolderListWidget extends ListWidget {
|
||||
constructor() {
|
@@ -1,4 +1,4 @@
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const ListWidget = require('tkwidgets/ListWidget.js');
|
||||
|
||||
class NoteListWidget extends ListWidget {
|
@@ -1,4 +1,4 @@
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const TextWidget = require('tkwidgets/TextWidget.js');
|
||||
|
||||
class NoteMetadataWidget extends TextWidget {
|
@@ -1,6 +1,6 @@
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const TextWidget = require('tkwidgets/TextWidget.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { _ } = require('lib/locale');
|
||||
|
||||
class NoteWidget extends TextWidget {
|
||||
constructor() {
|
@@ -1,6 +1,6 @@
|
||||
const { wrap } = require('@joplin/lib/string-utils.js');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { wrap } = require('lib/string-utils.js');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const { _ } = require('lib/locale');
|
||||
|
||||
const MAX_WIDTH = 78;
|
||||
const INDENT = ' ';
|
@@ -3,6 +3,9 @@
|
||||
// Use njstrace to find out what Node.js might be spending time on
|
||||
// var njstrace = require('njstrace').inject();
|
||||
|
||||
// Make it possible to require("/lib/...") without specifying full path
|
||||
require('app-module-path').addPath(__dirname);
|
||||
|
||||
const compareVersion = require('compare-version');
|
||||
const nodeVersion = process && process.versions && process.versions.node ? process.versions.node : '0.0.0';
|
||||
if (compareVersion(nodeVersion, '10.0.0') < 0) {
|
||||
@@ -11,24 +14,22 @@ if (compareVersion(nodeVersion, '10.0.0') < 0) {
|
||||
}
|
||||
|
||||
const { app } = require('./app.js');
|
||||
const Folder = require('@joplin/lib/models/Folder.js');
|
||||
const Resource = require('@joplin/lib/models/Resource.js');
|
||||
const BaseItem = require('@joplin/lib/models/BaseItem.js');
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const Tag = require('@joplin/lib/models/Tag.js');
|
||||
const NoteTag = require('@joplin/lib/models/NoteTag.js');
|
||||
const MasterKey = require('@joplin/lib/models/MasterKey');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const Revision = require('@joplin/lib/models/Revision.js');
|
||||
const Logger = require('@joplin/lib/Logger').default;
|
||||
const FsDriverNode = require('@joplin/lib/fs-driver-node').default;
|
||||
const sharp = require('sharp');
|
||||
const { shimInit } = require('@joplin/lib/shim-init-node.js');
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { FileApiDriverLocal } = require('@joplin/lib/file-api-driver-local.js');
|
||||
const EncryptionService = require('@joplin/lib/services/EncryptionService');
|
||||
const envFromArgs = require('@joplin/lib/envFromArgs');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const BaseItem = require('lib/models/BaseItem.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
const NoteTag = require('lib/models/NoteTag.js');
|
||||
const MasterKey = require('lib/models/MasterKey');
|
||||
const Setting = require('lib/models/Setting').default;
|
||||
const Revision = require('lib/models/Revision.js');
|
||||
const Logger = require('lib/Logger').default;
|
||||
const FsDriverNode = require('lib/fs-driver-node').default;
|
||||
const { shimInit } = require('lib/shim-init-node.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');
|
||||
|
||||
const env = envFromArgs(process.argv);
|
||||
|
||||
@@ -51,15 +52,7 @@ BaseItem.loadClass('Revision', Revision);
|
||||
Setting.setConstant('appId', `net.cozic.joplin${env === 'dev' ? 'dev' : ''}-cli`);
|
||||
Setting.setConstant('appType', 'cli');
|
||||
|
||||
let keytar;
|
||||
try {
|
||||
keytar = shim.platformSupportsKeyChain() ? require('keytar') : null;
|
||||
} catch (error) {
|
||||
console.error('Cannot load keytar - keychain support will be disabled', error);
|
||||
keytar = null;
|
||||
}
|
||||
|
||||
shimInit(sharp, keytar);
|
||||
shimInit();
|
||||
|
||||
const application = app();
|
||||
|
78
CliClient/app/services/plugins/PluginRunner.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
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):Promise<void> {
|
||||
return new Promise((resolve:Function, reject:Function) => {
|
||||
const onStarted = () => {
|
||||
plugin.off('started', onStarted);
|
||||
resolve();
|
||||
};
|
||||
|
||||
plugin.on('started', onStarted);
|
||||
|
||||
const vmSandbox = vm.createContext(this.newSandboxProxy(plugin.id, sandbox));
|
||||
|
||||
try {
|
||||
vm.runInContext(plugin.scriptText, vmSandbox);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
// this.logger().error(`In plugin ${plugin.id}:`, error);
|
||||
// return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@@ -1,4 +1,3 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
set -e
|
||||
npm run build && NODE_PATH="build/" node build/fuzzing.js
|
84
CliClient/gulpfile.js
Normal file
@@ -0,0 +1,84 @@
|
||||
const gulp = require('gulp');
|
||||
const fs = require('fs-extra');
|
||||
const utils = require('../Tools/gulp/utils');
|
||||
const tasks = {
|
||||
compileExtensions: {
|
||||
fn: require('../Tools/gulp/tasks/compileExtensions.js'),
|
||||
},
|
||||
copyLib: require('../Tools/gulp/tasks/copyLib'),
|
||||
tsc: require('../Tools/gulp/tasks/tsc'),
|
||||
updateIgnoredTypeScriptBuild: require('../Tools/gulp/tasks/updateIgnoredTypeScriptBuild'),
|
||||
};
|
||||
|
||||
tasks.prepareBuild = {
|
||||
fn: async () => {
|
||||
const buildDir = `${__dirname}/build`;
|
||||
await utils.copyDir(`${__dirname}/app`, buildDir, {
|
||||
excluded: ['node_modules'],
|
||||
});
|
||||
await utils.copyDir(`${__dirname}/locales-build`, `${buildDir}/locales`);
|
||||
await tasks.copyLib.fn();
|
||||
await utils.copyFile(`${__dirname}/package.json`, `${buildDir}/package.json`);
|
||||
await utils.copyFile(`${__dirname}/package-lock.json`, `${buildDir}/package-lock.json`);
|
||||
await utils.copyFile(`${__dirname}/gulpfile.js`, `${buildDir}/gulpfile.js`);
|
||||
|
||||
// Import all the patches inside the CliClient directory
|
||||
// and build file. Needs to be in CliClient dir for when running
|
||||
// in dev mode, and in build dir for production.
|
||||
const localPatchDir = `${buildDir}/patches`;
|
||||
await fs.remove(localPatchDir);
|
||||
await fs.mkdirp(localPatchDir);
|
||||
await utils.copyDir(`${__dirname}/../patches/shared`, `${localPatchDir}`, { delete: false });
|
||||
await utils.copyDir(`${__dirname}/../patches/node`, `${localPatchDir}`, { delete: false });
|
||||
|
||||
await fs.remove(`${__dirname}/patches`);
|
||||
await utils.copyDir(`${localPatchDir}`, `${__dirname}/patches`);
|
||||
|
||||
const packageRaw = await fs.readFile(`${buildDir}/package.json`);
|
||||
const package = JSON.parse(packageRaw.toString());
|
||||
package.scripts.postinstall = 'patch-package';
|
||||
await fs.writeFile(`${buildDir}/package.json`, JSON.stringify(package, null, 2), 'utf8');
|
||||
|
||||
fs.chmodSync(`${buildDir}/main.js`, 0o755);
|
||||
},
|
||||
};
|
||||
|
||||
tasks.prepareTestBuild = {
|
||||
fn: async () => {
|
||||
const testBuildDir = `${__dirname}/tests-build`;
|
||||
|
||||
await utils.copyDir(`${__dirname}/tests`, testBuildDir, {
|
||||
excluded: [
|
||||
'lib/',
|
||||
'locales/',
|
||||
'node_modules/',
|
||||
'*.ts',
|
||||
'*.tsx',
|
||||
],
|
||||
});
|
||||
|
||||
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`);
|
||||
},
|
||||
};
|
||||
|
||||
utils.registerGulpTasks(gulp, tasks);
|
||||
|
||||
gulp.task('build', gulp.series([
|
||||
'prepareBuild',
|
||||
'compileExtensions',
|
||||
'copyLib',
|
||||
]));
|
||||
|
||||
gulp.task('buildTests', gulp.series([
|
||||
'prepareTestBuild',
|
||||
'compileExtensions',
|
||||
'copyLib',
|
||||
]));
|