1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-06-24 23:26:50 +02:00

Mobile: Fixed mobile build

This commit is contained in:
Laurent Cozic
2021-01-27 17:42:58 +00:00
parent 35597ce3c2
commit 12187b9da3
24 changed files with 1247 additions and 79 deletions

View File

@ -664,6 +664,9 @@ packages/app-desktop/services/plugins/hooks/useWebviewToPluginMessages.js.map
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.d.ts packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.d.ts
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js.map packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js.map
packages/app-desktop/utils/markupLanguageUtils.d.ts
packages/app-desktop/utils/markupLanguageUtils.js
packages/app-desktop/utils/markupLanguageUtils.js.map
packages/app-mobile/PluginAssetsLoader.d.ts packages/app-mobile/PluginAssetsLoader.d.ts
packages/app-mobile/PluginAssetsLoader.js packages/app-mobile/PluginAssetsLoader.js
packages/app-mobile/PluginAssetsLoader.js.map packages/app-mobile/PluginAssetsLoader.js.map
@ -712,6 +715,9 @@ packages/app-mobile/utils/ShareExtension.js.map
packages/app-mobile/utils/checkPermissions.d.ts packages/app-mobile/utils/checkPermissions.d.ts
packages/app-mobile/utils/checkPermissions.js packages/app-mobile/utils/checkPermissions.js
packages/app-mobile/utils/checkPermissions.js.map packages/app-mobile/utils/checkPermissions.js.map
packages/app-mobile/utils/fs-driver-rn.d.ts
packages/app-mobile/utils/fs-driver-rn.js
packages/app-mobile/utils/fs-driver-rn.js.map
packages/app-mobile/utils/shareHandler.d.ts packages/app-mobile/utils/shareHandler.d.ts
packages/app-mobile/utils/shareHandler.js packages/app-mobile/utils/shareHandler.js
packages/app-mobile/utils/shareHandler.js.map packages/app-mobile/utils/shareHandler.js.map

6
.gitignore vendored
View File

@ -651,6 +651,9 @@ packages/app-desktop/services/plugins/hooks/useWebviewToPluginMessages.js.map
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.d.ts packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.d.ts
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js.map packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js.map
packages/app-desktop/utils/markupLanguageUtils.d.ts
packages/app-desktop/utils/markupLanguageUtils.js
packages/app-desktop/utils/markupLanguageUtils.js.map
packages/app-mobile/PluginAssetsLoader.d.ts packages/app-mobile/PluginAssetsLoader.d.ts
packages/app-mobile/PluginAssetsLoader.js packages/app-mobile/PluginAssetsLoader.js
packages/app-mobile/PluginAssetsLoader.js.map packages/app-mobile/PluginAssetsLoader.js.map
@ -699,6 +702,9 @@ packages/app-mobile/utils/ShareExtension.js.map
packages/app-mobile/utils/checkPermissions.d.ts packages/app-mobile/utils/checkPermissions.d.ts
packages/app-mobile/utils/checkPermissions.js packages/app-mobile/utils/checkPermissions.js
packages/app-mobile/utils/checkPermissions.js.map packages/app-mobile/utils/checkPermissions.js.map
packages/app-mobile/utils/fs-driver-rn.d.ts
packages/app-mobile/utils/fs-driver-rn.js
packages/app-mobile/utils/fs-driver-rn.js.map
packages/app-mobile/utils/shareHandler.d.ts packages/app-mobile/utils/shareHandler.d.ts
packages/app-mobile/utils/shareHandler.js packages/app-mobile/utils/shareHandler.js
packages/app-mobile/utils/shareHandler.js.map packages/app-mobile/utils/shareHandler.js.map

1095
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,8 @@
"buildTranslations": "npm run tsc && node packages/tools/build-translation.js", "buildTranslations": "npm run tsc && node packages/tools/build-translation.js",
"buildTranslationsNoTsc": "node packages/tools/build-translation.js", "buildTranslationsNoTsc": "node packages/tools/build-translation.js",
"buildWebsite": "npm run buildApiDoc && node ./packages/tools/build-website.js && npm run buildPluginDoc", "buildWebsite": "npm run buildApiDoc && node ./packages/tools/build-website.js && npm run buildPluginDoc",
"circularDependencyCheck": "npx madge --warning --circular --extensions js ./", "circularDependencyCheck": "madge --warning --circular --extensions js ./",
"dependencyTree": "madge",
"clean": "lerna clean -y && lerna run clean", "clean": "lerna clean -y && lerna run clean",
"generateDatabaseTypes": "node packages/tools/generate-database-types", "generateDatabaseTypes": "node packages/tools/generate-database-types",
"linkChecker": "linkchecker https://joplinapp.org", "linkChecker": "linkchecker https://joplinapp.org",
@ -60,6 +61,7 @@
"husky": "^3.0.2", "husky": "^3.0.2",
"lerna": "^3.22.1", "lerna": "^3.22.1",
"lint-staged": "^9.2.1", "lint-staged": "^9.2.1",
"madge": "^4.0.0",
"typedoc": "^0.17.8", "typedoc": "^0.17.8",
"typescript": "^4.0.5" "typescript": "^4.0.5"
} }

View File

@ -4,7 +4,7 @@ import { _ } from '@joplin/lib/locale';
const { themeStyle } = require('@joplin/lib/theme'); const { themeStyle } = require('@joplin/lib/theme');
const DialogButtonRow = require('./DialogButtonRow.min'); const DialogButtonRow = require('./DialogButtonRow.min');
const Countable = require('countable'); const Countable = require('countable');
import markupLanguageUtils from '@joplin/lib/markupLanguageUtils'; import markupLanguageUtils from '../utils/markupLanguageUtils';
interface NoteContentPropertiesDialogProps { interface NoteContentPropertiesDialogProps {
themeId: number; themeId: number;

View File

@ -25,7 +25,7 @@ import ToolbarButtonUtils from '@joplin/lib/services/commands/ToolbarButtonUtils
import { _ } from '@joplin/lib/locale'; import { _ } from '@joplin/lib/locale';
import TagList from '../TagList'; import TagList from '../TagList';
import NoteTitleBar from './NoteTitle/NoteTitleBar'; import NoteTitleBar from './NoteTitle/NoteTitleBar';
import markupLanguageUtils from '@joplin/lib/markupLanguageUtils'; import markupLanguageUtils from '../../utils/markupLanguageUtils';
import usePrevious from '../hooks/usePrevious'; import usePrevious from '../hooks/usePrevious';
import Setting from '@joplin/lib/models/Setting'; import Setting from '@joplin/lib/models/Setting';
import stateToWhenClauseContext from '../../services/commands/stateToWhenClauseContext'; import stateToWhenClauseContext from '../../services/commands/stateToWhenClauseContext';

View File

@ -1,7 +1,7 @@
import { PluginStates } from '@joplin/lib/services/plugins/reducer'; import { PluginStates } from '@joplin/lib/services/plugins/reducer';
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
import { ResourceInfos } from './types'; import { ResourceInfos } from './types';
import markupLanguageUtils from '@joplin/lib/markupLanguageUtils'; import markupLanguageUtils from '../../../utils/markupLanguageUtils';
import Setting from '@joplin/lib/models/Setting'; import Setting from '@joplin/lib/models/Setting';
const { themeStyle } = require('@joplin/lib/theme'); const { themeStyle } = require('@joplin/lib/theme');

View File

@ -15,7 +15,7 @@ const time = require('@joplin/lib/time').default;
const ReactTooltip = require('react-tooltip'); const ReactTooltip = require('react-tooltip');
const { urlDecode, substrWithEllipsis } = require('@joplin/lib/string-utils'); const { urlDecode, substrWithEllipsis } = require('@joplin/lib/string-utils');
const bridge = require('electron').remote.require('./bridge').default; const bridge = require('electron').remote.require('./bridge').default;
const markupLanguageUtils = require('@joplin/lib/markupLanguageUtils').default; const markupLanguageUtils = require('../utils/markupLanguageUtils').default;
class NoteRevisionViewerComponent extends React.PureComponent { class NoteRevisionViewerComponent extends React.PureComponent {
constructor() { constructor() {

View File

@ -16,7 +16,7 @@ const { ItemList } = require('../gui/ItemList.min');
const HelpButton = require('../gui/HelpButton.min'); const HelpButton = require('../gui/HelpButton.min');
const { surroundKeywords, nextWhitespaceIndex, removeDiacritics } = require('@joplin/lib/string-utils.js'); const { surroundKeywords, nextWhitespaceIndex, removeDiacritics } = require('@joplin/lib/string-utils.js');
const { mergeOverlappingIntervals } = require('@joplin/lib/ArrayUtils.js'); const { mergeOverlappingIntervals } = require('@joplin/lib/ArrayUtils.js');
import markupLanguageUtils from '@joplin/lib/markupLanguageUtils'; import markupLanguageUtils from '../utils/markupLanguageUtils';
const PLUGIN_NAME = 'gotoAnything'; const PLUGIN_NAME = 'gotoAnything';

View File

@ -0,0 +1,18 @@
import { MarkupLanguageUtils as BaseMarkupLanguageUtils } from '@joplin/lib/markupLanguageUtils';
import { PluginStates } from '@joplin/lib/services/plugins/reducer';
import { contentScriptsToRendererRules } from '@joplin/lib/services/plugins/utils/loadContentScripts';
class MarkupLanguageUtils extends BaseMarkupLanguageUtils {
public newMarkupToHtml(plugins: PluginStates, options: any = null) {
return super.newMarkupToHtml({
extraRendererRules: contentScriptsToRendererRules(plugins),
...options,
});
}
}
const markupLanguageUtils = new MarkupLanguageUtils();
export default markupLanguageUtils;

View File

@ -38,7 +38,7 @@ export default function useSource(noteBody: string, noteMarkupLanguage: number,
}, [themeId, paddingBottom]); }, [themeId, paddingBottom]);
const markupToHtml = useMemo(() => { const markupToHtml = useMemo(() => {
return markupLanguageUtils.newMarkupToHtml({}); return markupLanguageUtils.newMarkupToHtml();
}, [isFirstRender]); }, [isFirstRender]);
// To address https://github.com/laurent22/joplin/issues/433 // To address https://github.com/laurent22/joplin/issues/433

View File

@ -30,7 +30,7 @@ import SyncTargetOneDrive from '@joplin/lib/SyncTargetOneDrive';
const { AppState, Keyboard, NativeModules, BackHandler, Animated, View, StatusBar } = require('react-native'); const { AppState, Keyboard, NativeModules, BackHandler, Animated, View, StatusBar } = require('react-native');
const DropdownAlert = require('react-native-dropdownalert').default; const DropdownAlert = require('react-native-dropdownalert').default;
const AlarmServiceDriver = require('./services/AlarmServiceDriver'); const AlarmServiceDriver = require('./services/AlarmServiceDriver').default;
const SafeAreaView = require('./components/SafeAreaView'); const SafeAreaView = require('./components/SafeAreaView');
const { connect, Provider } = require('react-redux'); const { connect, Provider } = require('react-redux');
const { BackButtonService } = require('./services/back-button.js'); const { BackButtonService } = require('./services/back-button.js');
@ -90,7 +90,7 @@ SyncTargetRegistry.addClass(SyncTargetFilesystem);
SyncTargetRegistry.addClass(SyncTargetAmazonS3); SyncTargetRegistry.addClass(SyncTargetAmazonS3);
SyncTargetRegistry.addClass(SyncTargetJoplinServer); SyncTargetRegistry.addClass(SyncTargetJoplinServer);
const FsDriverRN = require('./utils/fs-driver-rn.js').FsDriverRN; import FsDriverRN from './utils/fs-driver-rn';
import DecryptionWorker from '@joplin/lib/services/DecryptionWorker'; import DecryptionWorker from '@joplin/lib/services/DecryptionWorker';
import EncryptionService from '@joplin/lib/services/EncryptionService'; import EncryptionService from '@joplin/lib/services/EncryptionService';
import MigrationService from '@joplin/lib/services/MigrationService'; import MigrationService from '@joplin/lib/services/MigrationService';

View File

@ -1,40 +1,40 @@
const RNFS = require('react-native-fs'); import FsDriverBase from '@joplin/lib/fs-driver-base';
const FsDriverBase = require('@joplin/lib/fs-driver-base').default;
const RNFetchBlob = require('rn-fetch-blob').default; const RNFetchBlob = require('rn-fetch-blob').default;
const RNFS = require('react-native-fs');
const { Writable } = require('stream-browserify'); const { Writable } = require('stream-browserify');
const { Buffer } = require('buffer'); const { Buffer } = require('buffer');
class FsDriverRN extends FsDriverBase { export default class FsDriverRN extends FsDriverBase {
appendFileSync() { public appendFileSync() {
throw new Error('Not implemented'); throw new Error('Not implemented');
} }
// Encoding can be either "utf8" or "base64" // Encoding can be either "utf8" or "base64"
appendFile(path, content, encoding = 'base64') { public appendFile(path: string, content: any, encoding = 'base64') {
return RNFS.appendFile(path, content, encoding); return RNFS.appendFile(path, content, encoding);
} }
// Encoding can be either "utf8" or "base64" // Encoding can be either "utf8" or "base64"
writeFile(path, content, encoding = 'base64') { public writeFile(path: string, content: any, encoding = 'base64') {
// We need to use rn-fetch-blob here due to this bug: // We need to use rn-fetch-blob here due to this bug:
// https://github.com/itinance/react-native-fs/issues/700 // https://github.com/itinance/react-native-fs/issues/700
return RNFetchBlob.fs.writeFile(path, content, encoding); return RNFetchBlob.fs.writeFile(path, content, encoding);
} }
// same as rm -rf // same as rm -rf
async remove(path) { public async remove(path: string) {
return await this.unlink(path); return await this.unlink(path);
} }
writeBinaryFile(path, content) { public writeBinaryFile(path: string, content: any) {
const buffer = Buffer.from(content); const buffer = Buffer.from(content);
return RNFetchBlob.fs.writeStream(path, 'base64').then(stream => { return RNFetchBlob.fs.writeStream(path, 'base64').then((stream: any) => {
const fileStream = new Writable({ const fileStream = new Writable({
write(chunk, encoding, callback) { write(chunk: any, _encoding: any, callback: Function) {
this.stream.write(chunk.toString('base64')); this.stream.write(chunk.toString('base64'));
callback(); callback();
}, },
final(callback) { final(callback: Function) {
this.stream.close(); this.stream.close();
callback(); callback();
}, },
@ -48,7 +48,7 @@ class FsDriverRN extends FsDriverBase {
} }
// Returns a format compatible with Node.js format // Returns a format compatible with Node.js format
rnfsStatToStd_(stat, path) { private rnfsStatToStd_(stat: any, path: string) {
return { return {
birthtime: stat.ctime ? stat.ctime : stat.mtime, // Confusingly, "ctime" normally means "change time" but here it's used as "creation time". Also sometimes it is null birthtime: stat.ctime ? stat.ctime : stat.mtime, // Confusingly, "ctime" normally means "change time" but here it's used as "creation time". Also sometimes it is null
mtime: stat.mtime, mtime: stat.mtime,
@ -58,7 +58,7 @@ class FsDriverRN extends FsDriverBase {
}; };
} }
async readDirStats(path, options = null) { public async readDirStats(path: string, options: any = null) {
if (!options) options = {}; if (!options) options = {};
if (!('recursive' in options)) options.recursive = false; if (!('recursive' in options)) options.recursive = false;
@ -69,7 +69,7 @@ class FsDriverRN extends FsDriverBase {
throw new Error(`Could not read directory: ${path}: ${error.message}`); throw new Error(`Could not read directory: ${path}: ${error.message}`);
} }
let output = []; let output: any[] = [];
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
const item = items[i]; const item = items[i];
const relativePath = item.path.substr(path.length + 1); const relativePath = item.path.substr(path.length + 1);
@ -80,19 +80,19 @@ class FsDriverRN extends FsDriverBase {
return output; return output;
} }
async move(source, dest) { public async move(source: string, dest: string) {
return RNFS.moveFile(source, dest); return RNFS.moveFile(source, dest);
} }
async exists(path) { public async exists(path: string) {
return RNFS.exists(path); return RNFS.exists(path);
} }
async mkdir(path) { public async mkdir(path: string) {
return RNFS.mkdir(path); return RNFS.mkdir(path);
} }
async stat(path) { public async stat(path: string) {
try { try {
const r = await RNFS.stat(path); const r = await RNFS.stat(path);
return this.rnfsStatToStd_(r, path); return this.rnfsStatToStd_(r, path);
@ -111,11 +111,11 @@ class FsDriverRN extends FsDriverBase {
// arguments but the function returns `false` and the timestamp is not set. // arguments but the function returns `false` and the timestamp is not set.
// Current setTimestamp is not really used so keep it that way, but careful if it // Current setTimestamp is not really used so keep it that way, but careful if it
// becomes needed. // becomes needed.
async setTimestamp() { public async setTimestamp() {
// return RNFS.touch(path, timestampDate, timestampDate); // return RNFS.touch(path, timestampDate, timestampDate);
} }
async open(path, mode) { public async open(path: string, mode: number) {
// Note: RNFS.read() doesn't provide any way to know if the end of file has been reached. // Note: RNFS.read() doesn't provide any way to know if the end of file has been reached.
// So instead we stat the file here and use stat.size to manually check for end of file. // So instead we stat the file here and use stat.size to manually check for end of file.
// Bug: https://github.com/itinance/react-native-fs/issues/342 // Bug: https://github.com/itinance/react-native-fs/issues/342
@ -128,17 +128,17 @@ class FsDriverRN extends FsDriverBase {
}; };
} }
close() { public close(): void {
return null; // Nothing
} }
readFile(path, encoding = 'utf8') { public readFile(path: string, encoding = 'utf8') {
if (encoding === 'Buffer') throw new Error('Raw buffer output not supported for FsDriverRN.readFile'); if (encoding === 'Buffer') throw new Error('Raw buffer output not supported for FsDriverRN.readFile');
return RNFS.readFile(path, encoding); return RNFS.readFile(path, encoding);
} }
// Always overwrite destination // Always overwrite destination
async copy(source, dest) { public async copy(source: string, dest: string) {
let retry = false; let retry = false;
try { try {
await RNFS.copyFile(source, dest); await RNFS.copyFile(source, dest);
@ -151,7 +151,7 @@ class FsDriverRN extends FsDriverBase {
if (retry) await RNFS.copyFile(source, dest); if (retry) await RNFS.copyFile(source, dest);
} }
async unlink(path) { public async unlink(path: string) {
try { try {
await RNFS.unlink(path); await RNFS.unlink(path);
} catch (error) { } catch (error) {
@ -164,7 +164,7 @@ class FsDriverRN extends FsDriverBase {
} }
} }
async readFileChunk(handle, length, encoding = 'base64') { public async readFileChunk(handle: any, length: number, encoding = 'base64') {
if (handle.offset + length > handle.stat.size) { if (handle.offset + length > handle.stat.size) {
length = handle.stat.size - handle.offset; length = handle.stat.size - handle.offset;
} }
@ -176,13 +176,15 @@ class FsDriverRN extends FsDriverBase {
return output ? output : null; return output ? output : null;
} }
resolve(path) { public resolve(path: string) {
throw new Error(`Not implemented: resolve(): ${path}`); throw new Error(`Not implemented: resolve(): ${path}`);
} }
resolveRelativePathWithinDir(_baseDir, relativePath) { public resolveRelativePathWithinDir(_baseDir: string, relativePath: string) {
throw new Error(`Not implemented: resolveRelativePathWithinDir(): ${relativePath}`); throw new Error(`Not implemented: resolveRelativePathWithinDir(): ${relativePath}`);
} }
}
module.exports.FsDriverRN = FsDriverRN; public async md5File(path: string): Promise<string> {
throw new Error(`Not implemented: md5File(): ${path}`);
}
}

View File

@ -3,7 +3,7 @@ const { GeolocationReact } = require('./geolocation-react.js');
const PoorManIntervals = require('@joplin/lib/PoorManIntervals').default; const PoorManIntervals = require('@joplin/lib/PoorManIntervals').default;
const RNFetchBlob = require('rn-fetch-blob').default; const RNFetchBlob = require('rn-fetch-blob').default;
const { generateSecureRandom } = require('react-native-securerandom'); const { generateSecureRandom } = require('react-native-securerandom');
const FsDriverRN = require('./fs-driver-rn.js').FsDriverRN; const FsDriverRN = require('./fs-driver-rn').default;
const urlValidator = require('valid-url'); const urlValidator = require('valid-url');
const { Buffer } = require('buffer'); const { Buffer } = require('buffer');
const { Linking, Platform } = require('react-native'); const { Linking, Platform } = require('react-native');

View File

@ -118,4 +118,12 @@ export default class FsDriverBase {
}; };
} }
public async tarExtract(_options: any) {
throw new Error('Not implemented');
}
public async tarCreate(_options: any, _filePaths: string[]) {
throw new Error('Not implemented');
}
} }

View File

@ -1,7 +1,7 @@
import { resolve as nodeResolve } from 'path'; import { resolve as nodeResolve } from 'path';
import FsDriverBase, { Stat } from './fs-driver-base'; import FsDriverBase, { Stat } from './fs-driver-base';
import time from './time'; import time from './time';
const md5File = require('md5-file/promise');
const fs = require('fs-extra'); const fs = require('fs-extra');
export default class FsDriverNode extends FsDriverBase { export default class FsDriverNode extends FsDriverBase {
@ -206,4 +206,16 @@ export default class FsDriverNode extends FsDriverBase {
return resolvedPath; return resolvedPath;
} }
public async md5File(path: string): Promise<string> {
return md5File(path);
}
public async tarExtract(options: any) {
await require('tar').extract(options);
}
public async tarCreate(options: any, filePaths: string[]) {
await require('tar').create(options, filePaths);
}
} }

View File

@ -2,26 +2,24 @@ import markdownUtils from './markdownUtils';
import Setting from './models/Setting'; import Setting from './models/Setting';
import shim from './shim'; import shim from './shim';
import MarkupToHtml, { MarkupLanguage } from '@joplin/renderer/MarkupToHtml'; import MarkupToHtml, { MarkupLanguage } from '@joplin/renderer/MarkupToHtml';
import { PluginStates } from './services/plugins/reducer';
import { contentScriptsToRendererRules } from './services/plugins/utils/loadContentScripts';
const htmlUtils = require('./htmlUtils'); const htmlUtils = require('./htmlUtils');
import Resource from './models/Resource'; import Resource from './models/Resource';
class MarkupLanguageUtils { export class MarkupLanguageUtils {
lib_(language: MarkupLanguage) { private lib_(language: MarkupLanguage) {
if (language === MarkupLanguage.Html) return htmlUtils; if (language === MarkupLanguage.Html) return htmlUtils;
if (language === MarkupLanguage.Markdown) return markdownUtils; if (language === MarkupLanguage.Markdown) return markdownUtils;
throw new Error(`Unsupported markup language: ${language}`); throw new Error(`Unsupported markup language: ${language}`);
} }
extractImageUrls(language: MarkupLanguage, text: string) { public extractImageUrls(language: MarkupLanguage, text: string) {
return this.lib_(language).extractImageUrls(text); return this.lib_(language).extractImageUrls(text);
} }
// Create a new MarkupToHtml instance while injecting options specific to Joplin // Create a new MarkupToHtml instance while injecting options specific to Joplin
// desktop and mobile applications. // desktop and mobile applications.
newMarkupToHtml(plugins: PluginStates, options: any = null) { public newMarkupToHtml(options: any = null) {
const subValues = Setting.subValues('markdown.plugin', Setting.toPlainObject()); const subValues = Setting.subValues('markdown.plugin', Setting.toPlainObject());
const pluginOptions: any = {}; const pluginOptions: any = {};
for (const n in subValues) { for (const n in subValues) {
@ -33,7 +31,6 @@ class MarkupLanguageUtils {
pluginOptions: pluginOptions, pluginOptions: pluginOptions,
tempDir: Setting.value('tempDir'), tempDir: Setting.value('tempDir'),
fsDriver: shim.fsDriver(), fsDriver: shim.fsDriver(),
extraRendererRules: contentScriptsToRendererRules(plugins),
}, options); }, options);
return new MarkupToHtml(options); return new MarkupToHtml(options);

View File

@ -198,7 +198,7 @@ export default class InteropService {
if (moduleMetadata.isCustom) { if (moduleMetadata.isCustom) {
output = this.newModuleFromCustomFactory(moduleMetadata); output = this.newModuleFromCustomFactory(moduleMetadata);
} else { } else {
const ModuleClass = require(this.modulePath(moduleMetadata)).default; const ModuleClass = shim.requireDynamic(this.modulePath(moduleMetadata)).default;
output = new ModuleClass(); output = new ModuleClass();
} }
@ -225,7 +225,7 @@ export default class InteropService {
output = this.newModuleFromCustomFactory(moduleMetadata); output = this.newModuleFromCustomFactory(moduleMetadata);
} else { } else {
const modulePath = this.modulePath(moduleMetadata); const modulePath = this.modulePath(moduleMetadata);
const ModuleClass = require(modulePath).default; const ModuleClass = shim.requireDynamic(modulePath).default;
output = new ModuleClass(); output = new ModuleClass();
} }
@ -248,7 +248,7 @@ export default class InteropService {
// if (moduleMetadata.isCustom) { // if (moduleMetadata.isCustom) {
// output = this.newModuleFromCustomFactory(moduleMetadata); // output = this.newModuleFromCustomFactory(moduleMetadata);
// } else { // } else {
// const ModuleClass = require(modulePath).default; // const ModuleClass = shim.requireDynamic(modulePath).default;
// output = new ModuleClass(); // output = new ModuleClass();
// } // }

View File

@ -7,6 +7,7 @@ import Note from '../../models/Note';
import Setting from '../../models/Setting'; import Setting from '../../models/Setting';
import { MarkupToHtml } from '@joplin/renderer'; import { MarkupToHtml } from '@joplin/renderer';
import { ResourceEntity } from '../database/types'; import { ResourceEntity } from '../database/types';
import { contentScriptsToRendererRules } from '../plugins/utils/loadContentScripts';
const { basename, friendlySafeFilename, rtrimSlashes } = require('../../path-utils'); const { basename, friendlySafeFilename, rtrimSlashes } = require('../../path-utils');
const { themeStyle } = require('../../theme'); const { themeStyle } = require('../../theme');
const { dirname } = require('../../path-utils'); const { dirname } = require('../../path-utils');
@ -38,7 +39,9 @@ export default class InteropService_Exporter_Html extends InteropService_Exporte
this.resourceDir_ = this.destDir_ ? `${this.destDir_}/_resources` : null; this.resourceDir_ = this.destDir_ ? `${this.destDir_}/_resources` : null;
await shim.fsDriver().mkdir(this.destDir_); await shim.fsDriver().mkdir(this.destDir_);
this.markupToHtml_ = markupLanguageUtils.newMarkupToHtml(options.plugins); this.markupToHtml_ = markupLanguageUtils.newMarkupToHtml({
extraRendererRules: contentScriptsToRendererRules(options.plugins),
});
this.style_ = themeStyle(Setting.THEME_LIGHT); this.style_ = themeStyle(Setting.THEME_LIGHT);
} }

View File

@ -34,15 +34,12 @@ export default class InteropService_Exporter_Jex extends InteropService_Exporter
if (!filePaths.length) throw new Error(_('There is no data to export.')); if (!filePaths.length) throw new Error(_('There is no data to export.'));
await require('tar').create( await shim.fsDriver().tarCreate({
{ strict: true,
strict: true, portable: true,
portable: true, file: this.destPath_,
file: this.destPath_, cwd: this.tempDir_,
cwd: this.tempDir_, }, filePaths);
},
filePaths
);
await fs.remove(this.tempDir_); await fs.remove(this.tempDir_);
} }

View File

@ -3,6 +3,8 @@ import { ImportExportResult } from './types';
import InteropService_Importer_Base from './InteropService_Importer_Base'; import InteropService_Importer_Base from './InteropService_Importer_Base';
import InteropService_Importer_Raw from './InteropService_Importer_Raw'; import InteropService_Importer_Raw from './InteropService_Importer_Raw';
const { filename } = require('../../path-utils'); const { filename } = require('../../path-utils');
import shim from '../../shim';
const fs = require('fs-extra'); const fs = require('fs-extra');
export default class InteropService_Importer_Jex extends InteropService_Importer_Base { export default class InteropService_Importer_Jex extends InteropService_Importer_Base {
@ -10,7 +12,7 @@ export default class InteropService_Importer_Jex extends InteropService_Importer
const tempDir = await this.temporaryDirectory_(true); const tempDir = await this.temporaryDirectory_(true);
try { try {
await require('tar').extract({ await shim.fsDriver().tarExtract({
strict: true, strict: true,
portable: true, portable: true,
file: this.sourcePath_, file: this.sourcePath_,

View File

@ -11,7 +11,6 @@ import RepositoryApi from './RepositoryApi';
import produce from 'immer'; import produce from 'immer';
const compareVersions = require('compare-versions'); const compareVersions = require('compare-versions');
const uslug = require('uslug'); const uslug = require('uslug');
const md5File = require('md5-file/promise');
const logger = Logger.create('PluginService'); const logger = Logger.create('PluginService');
@ -183,7 +182,7 @@ export default class PluginService extends BaseService {
baseDir = rtrimSlashes(baseDir); baseDir = rtrimSlashes(baseDir);
const fname = filename(path); const fname = filename(path);
const hash = await md5File(path); const hash = await shim.fsDriver().md5File(path);
const unpackDir = `${Setting.value('cacheDir')}/${fname}`; const unpackDir = `${Setting.value('cacheDir')}/${fname}`;
const manifestFilePath = `${unpackDir}/manifest.json`; const manifestFilePath = `${unpackDir}/manifest.json`;
@ -194,7 +193,7 @@ export default class PluginService extends BaseService {
await shim.fsDriver().remove(unpackDir); await shim.fsDriver().remove(unpackDir);
await shim.fsDriver().mkdir(unpackDir); await shim.fsDriver().mkdir(unpackDir);
await require('tar').extract({ await shim.fsDriver().tarExtract({
strict: true, strict: true,
portable: true, portable: true,
file: path, file: path,

View File

@ -4,7 +4,7 @@ import Joplin from './Joplin';
/** /**
* @ignore * @ignore
*/ */
const builtinModules = require('builtin-modules'); // const builtinModules = require('builtin-modules');
/** /**
* @ignore * @ignore
@ -12,7 +12,7 @@ const builtinModules = require('builtin-modules');
export default class Global { export default class Global {
private joplin_: Joplin; private joplin_: Joplin;
private requireWhiteList_: string[] = null; // private requireWhiteList_: string[] = null;
// private consoleWrapper_:any = null; // private consoleWrapper_:any = null;
constructor(implementation: any, plugin: Plugin, store: any) { constructor(implementation: any, plugin: Plugin, store: any) {
@ -40,22 +40,22 @@ export default class Global {
return this.joplin_; return this.joplin_;
} }
private requireWhiteList(): string[] { // private requireWhiteList(): string[] {
if (!this.requireWhiteList_) { // if (!this.requireWhiteList_) {
this.requireWhiteList_ = builtinModules.slice(); // this.requireWhiteList_ = builtinModules.slice();
this.requireWhiteList_.push('fs-extra'); // this.requireWhiteList_.push('fs-extra');
} // }
return this.requireWhiteList_; // return this.requireWhiteList_;
} // }
// get console(): any { // get console(): any {
// return this.consoleWrapper_; // return this.consoleWrapper_;
// } // }
require(filePath: string): any { // require(filePath: string): any {
if (!this.requireWhiteList().includes(filePath)) throw new Error(`Path not allowed: ${filePath}`); // if (!this.requireWhiteList().includes(filePath)) throw new Error(`Path not allowed: ${filePath}`);
return require(filePath); // return require(filePath);
} // }
// To get webpack to work with Node module we need to set the parameter `target: "node"`, however // To get webpack to work with Node module we need to set the parameter `target: "node"`, however
// when setting this, the code generated by webpack will try to access the `process` global variable, // when setting this, the code generated by webpack will try to access the `process` global variable,

View File

@ -1,3 +1,5 @@
'use strict';
const fs = require('fs-extra'); const fs = require('fs-extra');
const shim = require('./shim').default; const shim = require('./shim').default;
const { GeolocationNode } = require('./geolocation-node.js'); const { GeolocationNode } = require('./geolocation-node.js');
@ -23,6 +25,15 @@ function fileExists(filePath) {
} }
} }
// https://github.com/sindresorhus/callsites/blob/main/index.js
function callsites() {
const _prepareStackTrace = Error.prepareStackTrace;
Error.prepareStackTrace = (_any, stack) => stack;
const stack = new Error().stack.slice(1);
Error.prepareStackTrace = _prepareStackTrace;
return stack;
}
const gunzipFile = function(source, destination) { const gunzipFile = function(source, destination) {
if (!fileExists(source)) { if (!fileExists(source)) {
throw new Error(`No such file: ${source}`); throw new Error(`No such file: ${source}`);
@ -535,7 +546,17 @@ function shimInit(sharp = null, keytar = null, React = null) {
}; };
shim.requireDynamic = (path) => { shim.requireDynamic = (path) => {
return require(path); if (path.indexOf('.') === 0) {
const sites = callsites();
if (sites.length <= 1) throw new Error(`Cannot require file (1) ${path}`);
const filename = sites[1].getFileName();
if (!filename) throw new Error(`Cannot require file (2) ${path}`);
const fileDirName = require('path').dirname(filename);
return require(`${fileDirName}/${path}`);
} else {
return require(path);
}
}; };
} }